The common way to bind to AD as an LDAP server is to use "Distinguished Name(DN)" and Password. The DN usually is in the form of: CN=username,CN=Users,DC=yourdomain,DC=com
To find out DN, you can use Sysinternal's Active Directory Explorer to connect to AD and browse to the user to find out.
According to this post on stackoverflow, http://serverfault.com/questions/497368/ldap-activedirectory-binddn-syntax, you can also use UPN, which typically has the value of:
<sAMAccountName>@<domain FQDN>
October 31, 2014
Linux Frame buffer screen capture
1. Calculate the screen size. For example 1920 x 1080. Make sure that the width is a multiple of 4. For example, for HD screen resolution of 1366x768, use 1368x768
2. dd if=/dev/fb1 bs=1368 count=3072 | gzip -c > screen.bgra.gz
Each pixel is 4 byte, B-G-R-A. So 1368x768 resolution takes 1368*768*4=1368*3072 bytes
3. transfer the file to a Linux computer with imagemagick installed (needs a version released after 2010), and then convert it:
gunzip screen.bgra.gz
convert -size 1368x768 -depth 8 screen.bgra screen.png
2. dd if=/dev/fb1 bs=1368 count=3072 | gzip -c > screen.bgra.gz
Each pixel is 4 byte, B-G-R-A. So 1368x768 resolution takes 1368*768*4=1368*3072 bytes
3. transfer the file to a Linux computer with imagemagick installed (needs a version released after 2010), and then convert it:
gunzip screen.bgra.gz
convert -size 1368x768 -depth 8 screen.bgra screen.png
Kerberos simplified
The 6 steps of Kerberos
Players:
User
Service (Can be any service that user wants to access, such as mail service)
Kerberos Authentication Service (AS)
Kerberos Ticket Granting Service (TGS)
+--------------------+----------------------+
| | |
| Kerberos AS | Kerberos TGS |
| | |
+---------+----------+--------+-------------+
^ | ^ |
| | | |
1 | |2 3 | | 4
| | | |
| | | |
+-------------------+ | | | | +-----------------------+
| |--------------+ | | | | |
| |<--------------------+ | | | |
| +------------------------------------+ | | |
| User |<----------------------------------------+ 5 | Mail Service |
| +---------------------------------------------------------------->| |
| |<----------------------------------------------------------------+ |
+-------------------+ 6 +-----------------------+
Step 1: User ---- Username, Timestamp ----> Kerberos AS
Step 2: Kerberos AS ---- TGT=[K(user,tgs)<-P(tgs)], K(user,tgs)<-P(user) ----> User
Step 3: User ---- TGT<-P(tgs), user_name, service_name, authenticator<-K(user,tgs) ----> Kerberos TGS
Step 4: Kerberos TGS ---- ST=[K(user,service)<-P(service)], K(user,service)<-K(user,tgs) ----> User
Step 5: User ---- ST<-P(service), user_name, authenticator<-K(user,service) ----> Service
Step 6: Service ---- OK, authenticator<-K(user,service) ----> User
Authenticator = (sender_name, sender_address, timestamp, lifespan) <- SessionKey
K(user,tgs) : a session key, randomly generaged by Kerberos, shared betwee user and TGS
P(tgs) : a key based on the password of the tgs service. It's a password known only by the tgs service
P(user) : a key based on the password of the user
K(user,tgs)<-P(user) : meaning that K(user,tgs) is encrypted with the key of P(user)
TGT : Ticket Granting Ticket. It's just a token that needed for the user to talk to TGS. It contains
a session key known only by user and TGS.
Keytab files
In kerberos step 1, users can enter password to obtain the TGT from Kerberos TGS, what about services/devices? Kerberos allow the value P(user) to be exported and saved to a file, usually named keytab. This allows the service to authenticate users without talking to Kerberos server.
Players:
User
Service (Can be any service that user wants to access, such as mail service)
Kerberos Authentication Service (AS)
Kerberos Ticket Granting Service (TGS)
+--------------------+----------------------+
| | |
| Kerberos AS | Kerberos TGS |
| | |
+---------+----------+--------+-------------+
^ | ^ |
| | | |
1 | |2 3 | | 4
| | | |
| | | |
+-------------------+ | | | | +-----------------------+
| |--------------+ | | | | |
| |<--------------------+ | | | |
| +------------------------------------+ | | |
| User |<----------------------------------------+ 5 | Mail Service |
| +---------------------------------------------------------------->| |
| |<----------------------------------------------------------------+ |
+-------------------+ 6 +-----------------------+
Step 1: User ---- Username, Timestamp ----> Kerberos AS
Step 2: Kerberos AS ---- TGT=[K(user,tgs)<-P(tgs)], K(user,tgs)<-P(user) ----> User
Step 3: User ---- TGT<-P(tgs), user_name, service_name, authenticator<-K(user,tgs) ----> Kerberos TGS
Step 4: Kerberos TGS ---- ST=[K(user,service)<-P(service)], K(user,service)<-K(user,tgs) ----> User
Step 5: User ---- ST<-P(service), user_name, authenticator<-K(user,service) ----> Service
Step 6: Service ---- OK, authenticator<-K(user,service) ----> User
Authenticator = (sender_name, sender_address, timestamp, lifespan) <- SessionKey
K(user,tgs) : a session key, randomly generaged by Kerberos, shared betwee user and TGS
P(tgs) : a key based on the password of the tgs service. It's a password known only by the tgs service
P(user) : a key based on the password of the user
K(user,tgs)<-P(user) : meaning that K(user,tgs) is encrypted with the key of P(user)
TGT : Ticket Granting Ticket. It's just a token that needed for the user to talk to TGS. It contains
a session key known only by user and TGS.
Keytab files
In kerberos step 1, users can enter password to obtain the TGT from Kerberos TGS, what about services/devices? Kerberos allow the value P(user) to be exported and saved to a file, usually named keytab. This allows the service to authenticate users without talking to Kerberos server.
A really helpful story telling about Kerberos the authentication mechanism
http://web.mit.edu/kerberos/dialogue.html
I have read quite a few articles about Kerberos. Among them the above dialog is the most helpful. It does not hurt that it came from the original authors who help designed Kerberos.
I have read quite a few articles about Kerberos. Among them the above dialog is the most helpful. It does not hurt that it came from the original authors who help designed Kerberos.
October 17, 2014
Windows Server LDAP MaxPwdAge, MinPwdAge
When using AD Explorer software to query Windows Server, on a particular domain, you can see the maximum and minimum days required for password to change. These values show up as HEX values such as:
Max: 0xFFFFDEFF0AA68000
Min: 0xFFFFFF36D5964000
This is how to convert them to actual days:
( 0xFFFFFF36D5964000 - <64-bit value> ) / 0xC92A69C000 + 1 = answer ( in days)
Basically, the time unit here is 100ns (See http://en.wikipedia.org/wiki/System_time to see how Windows use 100ns as their system time unit). So
1 day is 24*3600*10,000,000 = 864000000000 = 0xC92A69C000
Starting from an unsigned 64-bit 0 value,
1 day = 0 - 0xC92A69C000 = 0xFFFFFF36D5964000
2 day2 = 0xFFFFFF36D5964000 - 0xC92A69C000 = 0xFFFFFE6DAB2C8000
3 days = 0xFFFFFDA480C2C000
...
41 days = 0xFFFFDFC835104000
42 days = 0xFFFFDEFF0AA68000
43 days = 0xFFFFDE35E03CC000
44 days = 0xFFFFDD6CB5D30000
...
89 days = 0xFFFFBA10413C4000
90 days = 0xFFFFB94716D28000
So for the above example:
Max: 42 days
Min: 1 day
Max: 0xFFFFDEFF0AA68000
Min: 0xFFFFFF36D5964000
This is how to convert them to actual days:
( 0xFFFFFF36D5964000 - <64-bit value> ) / 0xC92A69C000 + 1 = answer ( in days)
Basically, the time unit here is 100ns (See http://en.wikipedia.org/wiki/System_time to see how Windows use 100ns as their system time unit). So
1 day is 24*3600*10,000,000 = 864000000000 = 0xC92A69C000
Starting from an unsigned 64-bit 0 value,
1 day = 0 - 0xC92A69C000 = 0xFFFFFF36D5964000
2 day2 = 0xFFFFFF36D5964000 - 0xC92A69C000 = 0xFFFFFE6DAB2C8000
3 days = 0xFFFFFDA480C2C000
...
41 days = 0xFFFFDFC835104000
42 days = 0xFFFFDEFF0AA68000
43 days = 0xFFFFDE35E03CC000
44 days = 0xFFFFDD6CB5D30000
...
89 days = 0xFFFFBA10413C4000
90 days = 0xFFFFB94716D28000
So for the above example:
Max: 42 days
Min: 1 day
October 16, 2014
If you have a computer that joins to a domain, you can use LDAP to bind to the domain name controller and find a lot of information. Here is how you do it:
1. open a "cmd" window, and do: echo %logonserver% . This tells you the domain controller's name
2. download sysinternals AD explorer software, and connect to the domain controller
3. On the left tree, suppose your company's domain is abc.com, click on "DC=abc,DC=com"
4. In the subtree, click on "OU=...", and keep click on "OU=..." in the subtrees, until your find all the users with "CN=...". There you can see all the users of the domain, and all other information.
1. open a "cmd" window, and do: echo %logonserver% . This tells you the domain controller's name
2. download sysinternals AD explorer software, and connect to the domain controller
3. On the left tree, suppose your company's domain is abc.com, click on "DC=abc,DC=com"
4. In the subtree, click on "OU=...", and keep click on "OU=..." in the subtrees, until your find all the users with "CN=...". There you can see all the users of the domain, and all other information.
September 11, 2014
SNMP v3 trap and engineID
When sending an SNMP v3 trap from the sender to the trap receiver, the authoritative engineID is the trap sender's engine ID. Below is a method to remotely discover the engine ID of the remote SNMP sender (likely SNMP agent):
use the net-snmp snmpwalk command, and add the command option: "-Dsnmp_sess_open" and do a snmpget v3 with your credentials, and you should get something like this:
snmp_sess_open: probe found engineID: 80001f888016fb784553d902ac
.1.3.6.1.4.1.3432.8.1.1.7.0 = Gauge32: 0
You can also try "-Dlcd_get_enginetime", which gives you local engineID
use the net-snmp snmpwalk command, and add the command option: "-Dsnmp_sess_open" and do a snmpget v3 with your credentials, and you should get something like this:
snmp_sess_open: probe found engineID: 80001f888016fb784553d902ac
.1.3.6.1.4.1.3432.8.1.1.7.0 = Gauge32: 0
The agent's engineID is right there: 80001f888016fb784553d902ac
You can also try "-Dlcd_get_enginetime", which gives you local engineID
On the other note, I have written the SNMP trap receiver that can detect the incoming engineID automatically. Check it out at github: https://github.com/tiebingzhang/WapSNMP
On a local Linux machine running snmpd, you can find out its engine ID by:
cat /var/net-snmp/snmpd.conf
If you have any SNMP v3 user configured, you should see one or more lines like this:
usmUser 1 3 0x80001f888016fb784553d902ac 0x68636d2e736e6d70763300 0x......
EngineID is the 4th element: 0x80001f888016fb784553d902ac
September 10, 2014
On a Linux box find out actual serial port being used
1. cat /proc/tty/driver/serial
and
cat /proc/tty/driver/usbserial
2. dmesg | grep tty
3. setserial -g /dev/tty*
September 5, 2014
cross compile wpa_supplicant for arm
cd wpa_supplicant
edit the .config file, copy from a default one if you don't have one.
At the beginning of .config file, add:
CFLAGS += -I/opt/ezsdk/linux-devkit/arm-none-linux-gnueabi/usr/include -O2 -I../libnl/include -D_GNU_SOURCE
LIBS += -L/opt/ezsdk/linux-devkit/arm-none-linux-gnueabi/usr/lib/ -L../libnl/lib
CC=arm-none-linux-gnueabi-gcc
edit the .config file, copy from a default one if you don't have one.
At the beginning of .config file, add:
CFLAGS += -I/opt/ezsdk/linux-devkit/arm-none-linux-gnueabi/usr/include -O2 -I../libnl/include -D_GNU_SOURCE
LIBS += -L/opt/ezsdk/linux-devkit/arm-none-linux-gnueabi/usr/lib/ -L../libnl/lib
CC=arm-none-linux-gnueabi-gcc
Then make
Use "make V=1" to get verbose out.
September 4, 2014
cross compile nginx for ARM
nginx is a nice web server for embedded systems, but it is frustrating to cross compile because it does not use the standard autoconf structure, and the author provides no documentation to help make this process easier.
This is just my way of cross compiling it, feel fee to comment on your way.
1. compile it for your host. In my case, that's x86_64 Linux. I do the following:
./configure --without-pcre --without-http_rewrite_module
4. clean the old obj files:
find . -name "*.o" | xargs rm -f
5. make. The final binary is located objs/nginx
Note: make clean will remove the objs/Makefile you just changed. Make sure you have a backup.
This is just my way of cross compiling it, feel fee to comment on your way.
1. compile it for your host. In my case, that's x86_64 Linux. I do the following:
./configure --without-pcre --without-http_rewrite_module
make
2. Now, hand tweak the generated Makefie
vi objs/Makefile
replace the top few lines with the following (change it to your environment):
TOP := $(dir $(lastword $(MAKEFILE_LIST)))
CC = arm-none-linux-gnueabi-gcc
CFLAGS = -pipe -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Wunused-function -Wunused-variable -Wunused-value
CFLAGS += -I${TOP}/../openssl-1.0.1i/openssl-1.0.1i/include -I/opt/ezsdk/linux-devkit/arm-none-linux-gnueabi/usr/include
LINK = $(CC) -L${TOP}/../openssl-1.0.1i/
3. You may need to change the file objs/ngx_auto_config.h because some functions available on host are not available on your target. In my case, I had to remove lines containing ACCEPT4
4. clean the old obj files:
find . -name "*.o" | xargs rm -f
5. make. The final binary is located objs/nginx
Note: make clean will remove the objs/Makefile you just changed. Make sure you have a backup.
cross compile openssl 1.0.1i for ARM
export CROSS_COMPILE=arm-none-linux-gnueabi-
export ARCH=arm
./Configure shared linux-armv4
CC=${CROSS_COMPILE}gcc RANLIB=${CROSS_COMPILE}ranlib make
export ARCH=arm
./Configure shared linux-armv4
CC=${CROSS_COMPILE}gcc RANLIB=${CROSS_COMPILE}ranlib make
August 29, 2014
GO SNMP implementation
This is a open source SNMP trap receiver written in GO:
https://github.com/tiebingzhang/WapSNMP
It supports SNMP v2c and V3 traps.
It also includes utilities to perform SNMP Get and SNMP walk for both SNMP v2c and V3.
Since it is written in GO, it compiles on both Linux and Windows (and in theory also Mac OS, but not tested).
https://github.com/tiebingzhang/WapSNMP
It supports SNMP v2c and V3 traps.
It also includes utilities to perform SNMP Get and SNMP walk for both SNMP v2c and V3.
Since it is written in GO, it compiles on both Linux and Windows (and in theory also Mac OS, but not tested).
my .gitconfig
[user]
name = Tiebing Zhang
email = tzhang@advistatech.com
[core]
editor = vim
[merge]
tool = vimdiff
[alias]
d = difftool
st = status -s
ci = commit -a
br = branch
co = checkout
df = diff
dc = diff --cached
last = log -1 HEAD --stat
lg = log --stat
who = shortlog -s --
[diff]
renames = copy
tool = gvimdiff
[difftool "gvimdiff"]
cmd = "gvim -d" "$LOCAL" "$REMOTE"
[difftool]
prompt = false
[push]
default = matching
[sendpack]
sideband = false
GO cross compile Windows binary on Linux
# set up cross compilation to windows_amd64
# you only need to do this once
cd $GOROOT/src
GOOS=windows GOARCH=amd64 ./make.bash --no-clean
# whenever you want to cross compile
cd $YOUR_APP
GOOS=windows GOARCH=amd64 go build
More at
https://inconshreveable.com/04-30-2014/cross-compiling-golang-programs-with-native-libraries/
August 12, 2014
netcat send file with progress indicator
The following C code compiles to a file nc-send-file, and it will send a file to a raw tcp socket (such as netcat with the command: nc -l -p 8000 > myfile ), with progress indicator for every 64K bytes sent.
On Windows, compile it using MinGW the following Makefile:
nc-send-file:nc-send-file.c
gcc -Wall -O2 -o $@ $^ -s -lws2_32
clean:
rm -f nc-send-file.exe
C code:
#ifdef WIN32
#include "winsock2.h"
#else
#include "sys/socket.h"
#include "netinet/in.h"
#include "unistd.h"
#endif
#include "stdio.h"
int main(int argc, char**argv)
{
FILE * fd;
int sockfd,ret,n;
struct sockaddr_in servaddr;
char sendline[1024*64];
unsigned int totalbytes=0;
if (argc != 4)
{
printf("usage: client [IP address] [PORT] [File]\n");
exit(1);
}
#ifdef WIN32
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0){
fprintf(stderr, "WSAStartup() failed");
exit(1);
}
#endif
sockfd=socket(AF_INET,SOCK_STREAM,0);
memset(&servaddr,0,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr=inet_addr(argv[1]);
servaddr.sin_port=htons(atoi(argv[2]));
if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr))<0){
fprintf(stderr,"Error connecting to target.\n");
return -1;
}
fd=fopen(argv[3],"rb");
if (fd==NULL){
fprintf(stderr,"Opening file %s error\n",argv[3]);
return -1;
}
while (1){
ret=fread(sendline, 1, sizeof(sendline),fd);
if (ret==0){
if (feof(fd)){
printf("Finished. Total bytes sent:%u\n",totalbytes);
}else{
printf("Error.\n");
}
break;
}
n=send(sockfd,sendline,ret,0);
if (n!=ret){
printf("did not send all in the buffer. expecting %d sent %d exit.\n", ret, n);
return -1;
}
totalbytes+=ret;
printf("sending %d bytes, total %d bytes\n",ret, totalbytes);
}
fclose(fd);
#ifdef WIN32
closesocket(sockfd);
WSACleanup(); /* Cleanup Winsock */
#else
close(sockfd);
#endif
return 0;
}
August 8, 2014
xrdp reconnect to the same session
cat xrdp/xrdp.ini
[globals]
bitmap_cache=yes
bitmap_compression=yes
port=3389
crypt_level=high
channel_code=1
[xrdp1]
name=sesman-Xvnc
lib=libvnc.so
username=ask
password=ask
ip=127.0.0.1
port=-1
[xrdp2]
name=Reconnect
lib=libvnc.so
username=ask
password=ask
ip=127.0.0.1
#port=-1
port=5910
[globals]
bitmap_cache=yes
bitmap_compression=yes
port=3389
crypt_level=high
channel_code=1
[xrdp1]
name=sesman-Xvnc
lib=libvnc.so
username=ask
password=ask
ip=127.0.0.1
port=-1
[xrdp2]
name=Reconnect
lib=libvnc.so
username=ask
password=ask
ip=127.0.0.1
#port=-1
port=5910
Use stunnel to access https
stunnel -c -d localhost:8000 -r foo:443 -P /tmp/stunnel.pid -f
Now you can access local 8000 using plaintext so that you can debug and sniff packets.
Now you can access local 8000 using plaintext so that you can debug and sniff packets.
July 6, 2014
ipsec local routing bypass
Suppose that you have a ipsec site-to-site network as follows:
On local: from 10.1.0.0/16 to 0.0.0.0/0 goes to remote ipsec
On remote: from 0.0.0.0/0 to 10.1.0.0/16 goes to ipsec
Now on local you have a subnet 10.1.1.0/24 that you want to talk to. For example, you local interface eth1 has 10.1.1.1, and there is another computer on your network 10.1.1.2. Now if you want to ping 10.1.1.2 it would not work, because the traffic is captured by the ipsec policy (use "ip xfrm policy" to show it) and directed to ipsec tunnel.
To add local route bypass, use this:
ip xfrm policy add dir in src 10.1.1.0/24 dst 10.1.1.0/24
ip xfrm policy add dir out src 10.1.1.0/24 dst 10.1.1.0/24
On local: from 10.1.0.0/16 to 0.0.0.0/0 goes to remote ipsec
On remote: from 0.0.0.0/0 to 10.1.0.0/16 goes to ipsec
Now on local you have a subnet 10.1.1.0/24 that you want to talk to. For example, you local interface eth1 has 10.1.1.1, and there is another computer on your network 10.1.1.2. Now if you want to ping 10.1.1.2 it would not work, because the traffic is captured by the ipsec policy (use "ip xfrm policy" to show it) and directed to ipsec tunnel.
To add local route bypass, use this:
ip xfrm policy add dir in src 10.1.1.0/24 dst 10.1.1.0/24
ip xfrm policy add dir out src 10.1.1.0/24 dst 10.1.1.0/24
run this after your ipsec tunnel is up. Then you should be able to ping 10.1.1.2.
Note when I add polices directly use "setkey" it did not work for me.
Looks like StrongSwan can do this using config file section called "shunt" policies. Needs to try this.
Looks like StrongSwan can do this using config file section called "shunt" policies. Needs to try this.
July 3, 2014
sfdisk tips
sfdisk can be used to list partition information and alter partition tables
cat /proc/partitions to see the list of kernel recognized drivers and partitions
sfdisk -l : list information
sfdisk -l -u M : list information using MiB as unit.
sfdisk -l -u S : List information using sector (512 bytes) as unit.
Example:
sudo sfdisk -l /dev/sdc -u M
Disk /dev/sdc: 1044 cylinders, 255 heads, 63 sectors/track
Warning: extended partition does not start at a cylinder boundary.
DOS and Linux will interpret the contents differently.
Units = mebibytes of 1048576 bytes, blocks of 1024 bytes, counting from 0
Device Boot Start End MiB #blocks Id System
/dev/sdc1 * 1 7806 7806 7993344 83 Linux
/dev/sdc2 7807+ 8190 384- 392193 5 Extended
/dev/sdc3 0 - 0 0 0 Empty
/dev/sdc4 0 - 0 0 0 Empty
/dev/sdc5 7808 8190 383 392192 82 Linux swap / Solaris
Partition Alignment
When I tried to start partitioning on the 2nd cylinder instead of the first, I ran into issues. The command was:
My 80GB disk does not have a multiple of 2048 sectors, because the total number of sectors is a multiple of 63, which is the typical sectors per track. So to make my partition aligned at least to 4K, I used head of 16, which gives me the cylinder size of 63*16*512bytes=63*8KiB, so my cylinder is 4KiB aligned.
The above command will produce the following error:
sfdisk: Warning: given size (4096) exceeds max allowable size (1)
sfdisk: bad input
I was very puzzled. After compiling sfdisk from source code and adding debug statements in it, I finally found out the reason: sfdisk is trying to fit the 2nd partition in the first free cylinder because it think it is free! Well it is free except for the MBR in the first sector, but I don't want my 2nd partition to there. How do we tell sfdisk that? Here comes the "undocumented dangerous option" "--in-order". If you specify the "--in-order", sfdisk will work as you intended it to.
OR, you could manually specify the start address of each partition.
So the final working command is:
sfdisk /dev/sdb --in-order -H 16 -S 63 <<EOF
1,159,83
,4096,82
,,83
;
EOF
cat /proc/partitions to see the list of kernel recognized drivers and partitions
sfdisk -l : list information
sfdisk -l -u M : list information using MiB as unit.
sfdisk -l -u S : List information using sector (512 bytes) as unit.
Example:
sudo sfdisk -l /dev/sdc -u M
Disk /dev/sdc: 1044 cylinders, 255 heads, 63 sectors/track
Warning: extended partition does not start at a cylinder boundary.
DOS and Linux will interpret the contents differently.
Units = mebibytes of 1048576 bytes, blocks of 1024 bytes, counting from 0
Device Boot Start End MiB #blocks Id System
/dev/sdc1 * 1 7806 7806 7993344 83 Linux
/dev/sdc2 7807+ 8190 384- 392193 5 Extended
/dev/sdc3 0 - 0 0 0 Empty
/dev/sdc4 0 - 0 0 0 Empty
/dev/sdc5 7808 8190 383 392192 82 Linux swap / Solaris
Notice "7807+" and "384-" means that the numbers are not a multiple of MiB. Therefore that partition is not MiB aligned. For Extended partition, that is OK, but for real data-holding partitions, you may want them to be MiB aligned.
This is the list by sector results:
sudo sfdisk -l /dev/sdc -u S
Disk /dev/sdc: 1044 cylinders, 255 heads, 63 sectors/track
Warning: extended partition does not start at a cylinder boundary.
DOS and Linux will interpret the contents differently.
Units = sectors of 512 bytes, counting from 0
Device Boot Start End #sectors Id System
/dev/sdc1 * 2048 15988735 15986688 83 Linux
/dev/sdc2 15990782 16775167 784386 5 Extended
/dev/sdc3 0 - 0 0 Empty
/dev/sdc4 0 - 0 0 Empty
/dev/sdc5 15990784 16775167 784384 82 Linux swap / Solaris
Notice now there is no +/- anymore, and start/end are in sectors. This will give you exact layout of the partitions.
Write partitions:
sfdisk takes two kinds of formats as input to write partitions: the "manual" format as documented in the man page, and the "dump" format.
Use "-d" to dump the current partition table.
sudo sfdisk -d /dev/sdc
# partition table of /dev/sdc
unit: sectors
/dev/sdc1 : start= 2048, size= 15986688, Id=83, bootable
/dev/sdc2 : start= 15990782, size= 784386, Id= 5
/dev/sdc3 : start= 0, size= 0, Id= 0
/dev/sdc4 : start= 0, size= 0, Id= 0
/dev/sdc5 : start= 15990784, size= 784384, Id=82
Now you can edit this file, and then feed it back to change partitions using command "sfdisk -d /dev/sdc < part.txt", supposing that you wrote the above text to "part.txt" file.
Now some explanation of the "dump" format:
1. Empty lines are ignored
2. # and things after it is ignored (for that line)
3. "unit: sectors" is recognized as a valid command to set unit to sectors
4. Each partition line starts with the partition name, which is ignored. Then ":", then multiplle "variable-name=value" separated by ",". "bootable" is special because it is a boolean value.
5. All values have to be present. No auto calculation as in "manual" mode.
Partition Alignment
When I tried to start partitioning on the 2nd cylinder instead of the first, I ran into issues. The command was:
sfdisk /dev/sdb -H 16 -S 63
<<EOF
1,159,83
,4096,82
,,83
;
EOF
The above command will produce the following error:
sfdisk: Warning: given size (4096) exceeds max allowable size (1)
sfdisk: bad input
OR, you could manually specify the start address of each partition.
So the final working command is:
sfdisk /dev/sdb --in-order -H 16 -S 63 <<EOF
1,159,83
,4096,82
,,83
;
EOF
At last, you can use "hdparm -i" to list harddrive info, including number of LBA sectors. However, this may not work on some disks.
July 2, 2014
Understand fdisk output
Disk /dev/hdb: 64 heads, 63 sectors, 621 cylinders Units = cylinders of 4032 * 512 bytes Device Boot Start End Blocks Id System /dev/hdb1 * 1 184 370912+ 83 Linux /dev/hdb2 185 368 370944 83 Linux /dev/hdb3 369 552 370944 83 Linux /dev/hdb4 553 621 139104 82 Linux swap
Sector size: 512 bytes
64 Heads: there are 64/2=32 platters in the disk, each platter has 2 heads. Think head as a surface.
63 sectors: Each head is divided in to 63 sectors
621 cylinders: There are 621 of concentric tracks/cylinders on each head. Each track has 63 sectors as indicated above.
A cylinder is a vertical slice of a track on all heads. Cylinder size = #Heads * #sectors * 512 = 64*63*512 = 4032*512 = 2064384 bytes
Disk are allocated from low cylinders to high cylinders.
Start/End unit is cylinder.
Block size is 1024 bytes.
Blocks per cylinder is 2064384/1024 = 2016
The "+" sign in "370912+" means the number 3780912 is not accurate. The actual blocks should be a little more. To calculate the actual one, just do 370912/2016=183.98, and then rounded it up to get 184. So the first partition has 184 cylinders.
Another example:
Disk /dev/sda: 250.0 GB, 250059350016 bytes64 heads, 32 sectors/track, 238475 cylindersUnits = cylinders of 2048 * 512 = 1048576 bytesDevice Boot Start End Blocks Id System/dev/sda1 1 81 82928 83 Linux/dev/sda2 82 2082 2049024 83 Linux/dev/sda3 2083 238475 242066432 83 LinuxCylinder size = 64*32*512=1048576 (1MB)Blocks per cylinder = 1MB/1024=1024
Subscribe to:
Posts (Atom)