1 fwknopd是一个封装脚本。
2 如上文编译fwknop后,我选择的是gpg模式。
为了保证编译无优化,修改configure,将CFLAGS里所有-O2删掉
3 cd server/.libs/
gdb fwknop可进入
3 ldd fwknop可以看到
ldd fwknopd
linux-vdso.so.1 (0x00007ffc6d9cc000)
libfko.so.3 => /usr/lib/x86_64-linux-gnu/libfko.so.3 (0x00007f148f811000)
libpcap.so.0.8 => /usr/lib/x86_64-linux-gnu/libpcap.so.0.8 (0x00007f148f5d0000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f148f1df000)
libgpgme.so.11 => /usr/lib/x86_64-linux-gnu/libgpgme.so.11 (0x00007f148ef98000)
/lib64/ld-linux-x86-64.so.2 (0x00007f148fc4a000)
libassuan.so.0 => /usr/lib/x86_64-linux-gnu/libassuan.so.0 (0x00007f148ed85000)
libgpg-error.so.0 => /lib/x86_64-linux-gnu/libgpg-error.so.0 (0x00007f148eb70000)
这里稍微明显的是libfko这个文件,注意用对合适的就好。
cp *libfko.so.3.0.0.* /usr/lib/x86_64-linux-gnu/libfko.so.3.0.0.*
4 配置文件方面
目前默认的配置文件在/usr/local/etc/fwknop/fwknop.conf
可以-c指定,
access.conf可以在fwknop.conf里面指定。
5 调试配置文件的位置
(gdb) n
164 if (parse_access_folder(&opts, opts.config[CONF_ACCESS_FOLDER], &depth) != EXIT_SUCCESS)
(gdb) p CONF_ACCESS_FOLDER
$1 = CONF_ACCESS_FOLDER
(gdb) p opts.config
$2 = {0x5555557772b0 "/usr/local/etc/fwknop/fwknopd.conf", 0x0, 0x5555557775b0 "eth0", 0x0, 0x5555557775d0 "N", 0x555555777650 "udp port 62201", 0x5555557775f0 "100", 0x555555777610 "100000", 0x0, 0x555555777630 "Y", 0x555555777710 "1500",
0x555555777670 "Y", 0x555555777690 "120", 0x5555557776b0 "Y", 0x5555557776d0 "20", 0x0, 0x555555777a50 "N", 0x555555777a70 "N", 0x555555777a90 "N", 0x555555777ab0 "62201", 0x555555777ad0 "N", 0x555555777af0 "62201", 0x555555777b10 "500000", 0x0,
0x555555777b30 "fwknopd", 0x555555777b50 "LOG_DAEMON", 0x555555777990 "N", 0x5555557776f0 "N", 0x5555557779b0 "N", 0x5555557779d0 "Y", 0x555555777730 "N", 0x555555777750 "N", 0x555555777770 "N", 0x0, 0x555555777790 "N", 0x5555557777b0 "Y",
0x5555557777d0 "Y", 0x5555557777f0 "ACCEPT, filter, INPUT, 1, FWKNOP_INPUT, 1", 0x555555777830 "ACCEPT, filter, OUTPUT, 1, FWKNOP_OUTPUT, 1", 0x555555777870 "ACCEPT, filter, FORWARD, 1, FWKNOP_FORWARD, 1",
0x5555557778b0 "DNAT, nat, PREROUTING, 1, FWKNOP_PREROUTING, 1", 0x5555557778f0 "SNAT, nat, POSTROUTING, 1, FWKNOP_POSTROUTING, 1", 0x555555777930 "MASQUERADE, nat, POSTROUTING, 1, FWKNOP_MASQUERADE, 1", 0x555555777970 "Y",
0x555555777530 "/usr/local/var/fwknop", 0x555555777510 "/usr/local/etc/fwknop", 0x555555778520 "access.conf", 0x0, 0x555555777550 "/usr/local/var/fwknop/fwknopd.pid", 0x555555777580 "/usr/local/var/fwknop/digest.cache",
0x5555557779f0 "/root/.gnupg", 0x555555777a10 "/usr/bin/gpg", 0x555555777a30 "/usr/bin/sudo", 0x555555777290 "/sbin/iptables", 0x0, 0x0}
(gdb)
(gdb) p opts.config[CONF_ACCESS_FILE]
$3 = 0x555555778520 "access.conf"
(gdb)
这个配置对应
ACCESS_FILE /usr/local/etc/fwknop/access.conf;
6 对应的配置文件
fwknop.conf配置类似,
PCAP_INTF ens160;
ACCESS_FILE /usr/local/etc/fwknop/access.conf;
access.conf的配置如下
OPEN_PORTS tcp/22
SOURCE ANY 注意下面GPG的操作都要放在SOURCE下面,不然解析不到。
GPG_HOME_DIR /root/.gnupg
GPG_DECRYPT_ID A90C53 服务端
GPG_REMOTE_ID 24F 客户端
GPG_ALLOW_NO_PW Y 使用无需密码的GPG
GPG_REQUIRE_SIG N 不需要对签名进行验签?
GPG_DISABLE_SIG Y
GPG_REQUIRE_SIG N
注意GPG的配置要放在SOURCE里面。
对于fwknopd的配置来说,为了区分多用户,导致配置前后顺序是非常有关联性的,千万不要和普通的conf一样,以为配置没有先后顺序。这种按节区分的配置方式,他们叫做“stanza”,就是一节。韵诗里面的一节。
7 解析access.conf的如下,
parse_access_file
这里while解析每字段是够长的
终于关闭,如果是1层,不包括include文件的情况,
if(*depth == 0) //means we just closed the root access.conf
{
if(curr_acc != NULL)
{
if(!acc_data_is_valid(opts, user_pw, sudo_user_pw, curr_acc))
{
log_msg(LOG_ERR,
"[*] Data error in access file: '%s'",
access_filename);
return EXIT_FAILURE;
}
}
else if (opts->acc_stanzas == NULL)
{
log_msg(LOG_ERR,
"[*] Could not find valid SOURCE stanza in access file: '%s'",
opts->config[CONF_ACCESS_FILE]);
return EXIT_FAILURE;
}
/* Expand our the expandable fields into their respective data buckets.
*/
expand_acc_ent_lists(opts);
/* Make sure default values are set where needed.
*/
set_acc_defaults(opts);
}
8 acc_data_is_valid
检查access.conf里的数据合规性
9
客户端配置gpg,使用fwknod-gui来配置,
使用方法如下,
选择gpg,加密密钥(encr key)是615F,是服务端ID的最后几位
签名密钥(sign key)是9884,是客户端ID的最后8位
10,
包处理
(gdb) bt
#0 check_mode_ctx (spadat=0x7ffe40e899f0, ctx=0x7ffe40e899c8, attempted_decrypt=1, enc_type=2, stanza_num=1, res=138) at incoming_spa.c:552
#1 0x000056013b20511a in incoming_spa (opts=0x7ffe40e8b1e0) at incoming_spa.c:1015
#2 0x000056013b2064bf in process_packet (args=0x7ffe40e8b1e0 "", packet_header=0x7ffe40e8af60, packet=0x7f6530d00086 "") at process_packet.c:233
#3 0x00007f65319660b6 in ?? () from /usr/lib/x86_64-linux-gnu/libpcap.so.0.8
#4 0x00007f6531966d64 in ?? () from /usr/lib/x86_64-linux-gnu/libpcap.so.0.8
#5 0x000056013b205dfd in pcap_capture (opts=0x7ffe40e8b1e0) at pcap_capture.c:227
#6 0x000056013b1ff7b6 in main (argc=1, argv=0x7ffe40e8bf18) at fwknopd.c:296
(gdb)
11 服务端调试的情况,
发现在fko_ctx->verify_gpg_sigs 设置为0后,可以正常解密。
目前是verify_gpg_sigs 的时候有失败。
Breakpoint 2, gpgme_decrypt (fko_ctx=0x55bb9af25780,
indata=0x55bb9af25890 "\205\001\214\003\365\006\036\067\037!\343=\001\v\376'\252;ZjeC\206\256锚\256\371\237p\a\372R|\271\273\bp\300\315;\242A\n\252\251\315\026\340+`lA\273\272\275\363_\030\232U\016\223O\006s\201\a\246\334\344\366\242\227\241;:H卸ae\307Y\370}\274F-N\005q\317\311!\031\020\203\317\067^\237\071\325\336tA\307g\351\231J\321\376\336u\322G\217F{:\252慕\265\065\"y4\204h7\266s\210\311瓢\335\372?l\377\\0\020\233\357\364\360\356\346\071a\242憧.\316R\304!\201\253e\226Bb\254\356:\271\246[_\221\237\034\033'B\335\377\312\r\223\"\347\a\326\374P\360\312\344F\v"..., in_len=717, pw=0x55bb9af23db0 "", out=0x55bb9af257f0, out_len=0x7ffcfbcb8240) at gpgme_funcs.c:500
500 if(fko_ctx->verify_gpg_sigs)
(gdb) p fko_ctx
$1 = (fko_ctx_t) 0x55bb9af25780
(gdb) p fko_ctx->verify_gpg_sigs
$2 = 1 '\001'
(gdb) set fko_ctx->verify_gpg_sigs=0
(gdb) p fko_ctx->verify_gpg_sigs
$3 = 0 '\000'
(gdb) b 524
Breakpoint 3 at 0x7fec6d633864: file gpgme_funcs.c, line 524.
(gdb) c
Continuing.
Breakpoint 3, gpgme_decrypt (fko_ctx=0x55bb9af25780,
indata=0x55bb9af25890 "\205\001\214\003\365\006\036\067\037!\343=\001\v\376'\252;ZjeC\206\256锚\256\371\237p\a\372R|\271\273\bp\300\315;\242A\n\252\251\315\026\340+`lA\273\272\275\363_\030\232U\016\223O\006s\201\a\246\334\344\366\242\227\241;:H卸ae\307Y\370}\274F-N\005q\317\311!\031\020\203\317\067^\237\071\325\336tA\307g\351\231J\321\376\336u\322G\217F{:\252慕\265\065\"y4\204h7\266s\210\311瓢\335\372?l\377\\0\020\233\357\364\360\356\346\071a\242憧.\316R\304!\201\253e\226Bb\254\356:\271\246[_\221\237\034\033'B\335\377\312\r\223\"\347\a\326\374P\360\312\344F\v"..., in_len=717, pw=0x55bb9af23db0 "", out=0x55bb9af257f0, out_len=0x7ffcfbcb8240) at gpgme_funcs.c:524
524 *out = calloc(1, *out_len+1); /* This is freed upon fko_ctx destruction. */
(gdb) p *out_len
$4 = 102
(gdb) p tmp_buf
$5 = 0x55bb9af2a380 "1556910099159132:cGFuMno:1664754107:3.0.0:3:MjIzLjcyLjc1LjEzNix0Y3AvMjI:60:ls0yWC0Y+qTih+LXPO0TJQDsMmM"
(gdb)
12
解码出来的这段文字还是对的。
"1556910099159132:cGFuMno:1664754107:3.0.0:3:MjIzLjcyLjc1LjEzNix0Y3AvMjI:60:ls0yWC0Y+qTih+LXPO0TJQDsMmM"
13
cipher = enc(plaintext, key,rsa),这里明文和key都是固定的, 算法是rsa,加密内容是变化的?
答复:plaintext里面包含时间戳,所以plaintext本身是变化的。如果plaintext是变化的,那么cipher是变化的是理所当然的。但是是不是明文和key都固定的情况,加密内容是变化的,目前看似乎不是变化的。因为除非enc()是随机函数,对于类多项式的函数来说不大可能算法,明文,密钥是固定的,反而加密密文是变化的。