分类目录归档:网络

对各种网络问题的研究

RouterOS上抵挡扫描的防火墙策略

背景

因为家里的宽带是找电信要了公网IP地址的,所以互联网可以直接访问到我作为出口的RouterOS,而众所周知,互联网上扫描机不知何几,被盯上了的话也是一件相当麻烦的事。

起因

之前在玩RouterOS上的防火墙的时候,发现有一个动作,叫做“add src to address list”,能够将包的源地址添加到某个列表中。俺寻思了一下,发现这能够很好的抵挡扫描机,思路是这样的:

防火墙策略

建立防火墙策略,指定一些经常被扫描的目的端口,然后,防火墙的动作是将包的源地址添加到一个叫做sniffer的地址列表中,设定有效时间为30天,然后,让防火墙直接丢弃来自这些地址的包,这样如果某个机器尝试扫描我的出口,触发了这个机制,那这个机器就会直接被ban掉30天。

命令行的话,添加起来是这样的:

/ip firewall filter add action=drop chain=input comment="drop sniffer" in-interface=China-Telecom src-address-list=sniffer
/ip firewall filter add action=add-src-to-address-list address-list=sniffer address-list-timeout=30d chain=input comment="mark sniffer" dst-port=22,23,876,3306,3389,137,139,445,5001,6379,27017 in-interface=China-Telecom log=yes log-prefix=sniffer protocol=tcp
/ip firewall filter add action=add-src-to-address-list address-list=sniffer address-list-timeout=30d chain=input comment="mark sniffer" dst-port=22,23,876,3306,3389,137,139,445,5001,6379,27017 in-interface=China-Telecom log=yes log-prefix=sniffer protocol=udp
/ip firewall filter add action=add-src-to-address-list address-list=sniffer address-list-timeout=30d chain=input comment="mark sniffer" dst-port=2323,5555,80,81,37215,8000,8080,8081,8291,8443,53 in-interface=China-Telecom log=yes log-prefix=sniffer protocol=tcp
/ip firewall filter add action=add-src-to-address-list address-list=sniffer address-list-timeout=30d chain=input comment="mark sniffer" dst-port=2323,5555,80,81,37215,8000,8080,8081,8291,8443 in-interface=China-Telecom log=yes log-prefix=sniffer protocol=udp
/ip firewall filter add action=drop chain=input comment="drop sniffer" in-interface=China-Telecom src-address-list=sniffer

然后放着一阵子,就会在address list里面看到大量的IP地址。

继续改进

如果想要更加全面的保护,可以选择在防火墙上添加允许一些正常的策略,比如说,允许每秒不超过20个echo-request的icmp包啊之类的,然后在防火墙的末尾,加一条策略,将其他未知的包,都当作扫描机处理,一律有杀错无放过。

但是有时候,ban了对方的ip,也就意味着无法访问对方的IP地址,因为回包会被防火墙丢弃。这时候就要额外的添加一条策略,插在丢弃sniffer的策略的前面:

action是accept就可以了。这样如果是主动对外访问的话,回的包要么是related,要么是established,这样就可以正常访问被ban掉的ip。至于说udp访问可能没有这个状态标记……先暂时忽略吧,出现问题再继续改进。

Windows Server作为Mikrotik设备管理员的3A服务器

在使用了Mikrotik的RouterOS作为出口路由使用了相当一段时间之后,我彻底成为了ROS的粉丝,现在手里有一个x86的小机和一直RB750Gr3分别在家里和出租屋做出口路由。

虽然设备不多,管理员也就我一个,根本没有3A什么的出场的机会,只不过嘛,生命在于折腾,研究研究不是也很好嘛。

安装NAPS服务器并配置

首先,安装网络访问策略服务器(NAPS),这可以用来作为Radius服务器。通过服务器管理器添加角色与功能,一路下一步,在角色一页勾选上“网络策略与访问服务”,然后继续下一步直至安装完毕为止。我因为懒得卸掉重装,后面的就没继续截图了。

安装完NPS之后,就可以开始配置。当然,首先,是添加用户组,并将用户添加到组,顺便确认一下用户的拨入属性由NAPS控制。

然后,去网络策略服务器,添加radius客户端。允许ROS使用NPS作为radius服务器。IP地址写ROS使用的源地址,机密随意只要和ROS设备上一样即可。

下一步是新建网络策略,填写策略名称之后,服务类型选择未指定。

然后下一步里面,指定匹配那个Mikrotik管理员组;这时候可以限定NAS标识符或者限定被叫站ID(前者默认是ROS的system identity,后者默认是radius客户端的IP地址)。

选择匹配策略的授权访问。至于身份验证方法,暂时知道ROS使用的mschapv2,以后会不会改就不知道了。至于约束,默认下一步。

到了配置设置的一步,把默认的两个标准删掉,手动添加Service-Type,值为Login,虽然默认的似乎也能用。

然后就是精华所在:在“供应商特定”一项里面,手动添加一个属性,属性是Vendor-Specific,添加。添加一个属性,供应商为“14988”,符合RFC规格,然后配置属性。供应商分配的属性号为3,属性格式为字符串,属性值就是用户组的名字。系统默认最高权限的组的名字是full,我这里填的就是full。

然后禁用BAP(因为感觉没什么乱用,似乎不禁用也行),下一步,完成。Windows Server这边就OK了。

配置ROS

首先,选好ROS的系统名称,保证能够匹配到NAPS上的那个过滤策略。

然后,在ROS上配置Radius客户端。Service选择login就行,address填NAPS的地址,Secret就是刚才在NAPS添加Radius客户端的机密,同时,建议指定一下源地址,特别是ROS有多个接口IP地址的时候。

下一步,在system-users中启用AAA登录,Default Group选择最低权限的一个,那就行了。

最后验证一下,大功告成!

使用PXE从NFS服务器启动Debian Linux

一、开篇

首先,我使用的是debian的linux,版本是stretch,其他发行版的话只能作为参考,无法照搬。

然后上参考:https://blog.csdn.net/politefish/article/details/4444417

在网上搜无盘系统,全部都是指导怎么启动安装器的,这个我之前已经做过了,没什么问题,但是如何做一个能直接运行的linux,倒还是第一次。上边这边文章里面洋洋撒撒一大串,不过还是指引了我找到了比较核心的内容。

二、组件部署

首先PXE启动系统我这边就不说了,参考有很多,比如说这个这个,还有这个。总所周之,PXE启动linux需要3个组件,一个DHCP服务器,一个tftp服务器,还有一个NFS服务器。因为我家的路由器系统都比较的有好,DHCP服务器方面都支持设置PXE的引导,所以不需要额外的架设一个DHCP服务器。

tftp服务器和NFS服务器我是使用我家的一台QNAP的NAS来做的,性能和整合度不错,由于是同一份文件的不同共享,所以就不需要每次更新了kernel之后还需要单独将kernel拷贝到tftp服务器去了。

 

首先是tftp服务器,先把tftp服务器开起来,指向目标,限制好来源

然后参考这个,把所需的文件放到目标

看起来像是这样:

PXE
├── debian
│ └── #这里放Debian的系统
├── ldlinux.c32
├── libcom32.c32
├── libutil.c32
├── pxelinux.0
├── pxelinux.cfg
│ └── default
└── vesamenu.c32

再然后就是NFS系统,在系统中调整NFS分享,让/PXE能够以NFS的形式挂载,这就可以了,如何建立NFS服务器并且建立共享,这里不多说。

三、系统安装

然后先安装好基本系统,再回来修改default的配置文件

参考了网上搜出来的文章,我发现他用的方法就是使用debootstrap来安装系统。嗯?看着眼熟,不就是我当年做过的事情吗?哎呀,这就容易了嘛。

这里我选择的方法是用containerstation跑个LXC容器,将文件夹挂载到容器中。如果手边只有windows的机器,可以选择上虚拟机,然后挂载NFS共享。

假设将目标挂载到/mnt,就可以使用这样的方式来安装基本的debian系统

 

debootstrap –arch=amd64 stretch /mnt/ http://ftp.cn.debian.org/debian/

然后稍作等待,你就获得了一个debian系统了。当然,推荐使用同一个架构的CPU,因为这样接下来的后续安装就会方便很多。

chroot到新系统之后就可以向刚安装的系统一样去做后期的调整了。注意至少有一下这么几个

1.修改root的密码

2.新增用户

以下几个我是当时做了的配置但看起来并不是必须的,酌情参考

3.修改fstab和mtab,详细看参考链接,但是我登录系统之后看mount表完全不是那么一回事

4.配置网络,参考链接里面还是用的eth0,但是我登录系统后看到的接口都不是eth0而是en0了,又是一个过期的文档

5.调整时区,这个最好做一下,还有用timedatectl set-local-rtc 1 设置将RTC时钟设为本地时间而不是UTC时间,避免和windows来回切的时候导致windows时间混乱

然后把你想安装的东西都安装上。duang,系统就安装好了。

四、调整PXE启动配置

最后回来调整一下PXE的启动文件,这里是最精华的地方:

DEFAULT vesamenu.c32
PROMPT 0
MENU TITLE Home PXE-Boot Server
label Diskless Debian
MENU LABEL Diskless Debian
KERNEL debian/vmlinuz
append vga=normal initrd=debian/initrd.img ramdisk_size=14332 root=/dev/nfs nfsroot=NFS服务器地址:/PXE/debian rw --
TEXT HELP
Starts the Diskless Debian
ENDTEXT

需要注意的是,这里是系统的根目录下存在两个指向boot的链接,所以kernel和initrd才是这个位置,至于其他的参数,我暂时还没了解到如何使用,先保留着,看以后是否再需要优化。

配置完成后,就可以启动主机,然后选择从LAN启动了,启动之后,可以看到根目录是从nfs服务器挂载的。

 

在使用动态ip的情况下使用tunnelbroker

最近我家不知为啥,pppoe拨号基本上每天晚上都会断一次,而重连之后由于ip地址变更,6to4的tunnel就中断了,一次两次就算了,每天都一次的话就不能靠手动,等靠自动化来维护。

参考:

https://wiki.mikrotik.com/wiki/Manual:Scripting-examples

https://gist.github.com/pklaus/960672

最开始是打算看看RouterOS能不能在接口启动之后触发运行一次脚本,但是ppp的profile里面的那个up down的scripts触发并没有效果(或许是我用法不对?)于是只能换一种思路,定时检查ip有没有变更,如果变更了,就触发一次配置更新。

两个脚本大概是这样:

脚本check_ip_change:检查ip有没有出现变更:

:global currentIP;
:local newIP [/ip address get [find interface="wan"] address];
:if ($newIP != $currentIP) do={
 /system script run update_sit;
 :set currentIP $newIP;
}

脚本update_sit:执行更新interface属性以及向tunnelbroker通知客户端节点地址变更:

local ipaddr
local users "someuser"
local key "somekey"
local tunnelid "sometunnelid"
:set ipaddr [/ip address get [/ip address find interface=wan] address]
:set ipaddr [:pick $ipaddr 0 ([len $ipaddr] -3)]
/interface 6to4 set sit1 local-address=$ipaddr
/tool fetch url="https://$users:$key@ipv4.tunnelbroker.net/nic/update?hostname=$tunnelid&myip=$ipaddr" mode=https keep-result=no

然后定制每分钟执行一次check_ip_change,然后在下次ip地址变更之后,就可以在1分钟内完成自动修复了。

在RouterOS上使用Tunnelbroker的ipv6服务

参考:https://my.oschina.net/CandyMi/blog/500882

首先,你需要一个公网的ipv4地址,至少是能ping通的,那种能ping得到但是在防火墙后面的情况,我也没试过,这里就不多说。

以下是步骤:

1:前往https://www.tunnelbroker.net/注册一个账号,操作过程不详述;

2:登陆成功后在左侧选择新增一个tunnel

在ipv4的节点上填写你的ipv4地址,截图我是直接扒原博文的,看来他是已经搭好了tunnel再去访问的

根据你的链接速度来选择对应的服务器,选好后create tunnel就可以完成创建了。

3:完成tunnel的创建,接下来就是配置,在example configurations页可以选择大部分系统的配置命令,选择mikrotik的,可以直接给出配置的命令,方便的很。

到此,RouterOS已经能得到一个/64的地址块,可以用这个地址块来分ipv6给内网的设备了。

4:现在你手里已经有了一个/64的地址块,需要注意的是分配给你的地址块和tunnel的客户端地址不属于同一个/64地址块,tunnel的信息页面上有加粗标识,不要搞混了,Routed IPv6 Prefixes才是给子网用的。

在/ipv6/pool新增一个地址池,名字随便起一个,比如说sit,然后把你得到的这个/64地址块拷进去,保存。

5:然后就可以新增一个ipv6的dhcp服务器,pool选择sit,选好应用的接口,至此,RouterOS就可以承担dhcp服务器的作用了,给客户端分配公网的ipv6地址。

6:最后,在/ipv6/route中添加ipv6的默认路由,然后RouterOS以及下面的整个子网都可以访问ipv6网络了。

RouterOS上的pxe服务器

因为骨干路由从OpenWRT换到了RouterOS,所以pxe服务器也得从新搭建。

过程不是很麻烦,但是RouterOS并没有nfs服务器,所以有些linux发行版的netboot需要nfs的,就需要什么额外的机器来当这个nfs服务器了,当然,kvm是个好东西。

可以参考之前的老文https://ferrets.space/2014/04/07/在家里做了个pxe服务器/,有些东西还是自己动手丰衣足食。

目前拿了个debian来做实验:

首先,去下载必要的文件,然后,找到

pxelinux.0
ldlinux.c32
vesamenu.c32
libcom32.c32
libutil.c32
pxelinux.cfg/default
linux
initrd.gz

接下来首先就是要编辑pxelinux的配置文件pxelinux.cfg/default,内容可以参考之前的文章,大概像这样子:

DEFAULT vesamenu.c32
PROMPT 0
MENU TITLE RouterOS PXE-Boot Server

label Ubuntu
        MENU LABEL Debian
        KERNEL debian/linux
        APPEND initrd=debian/initrd.gz
        TEXT HELP
                Starts the Debian Net installer
        ENDTEXT

至于各字段怎么自定义那就自行Google了,保存好配置文件之后呢,就将这么几个文件,丢到RouterOS的文件系统(真他么的不好用)里,比如说这样:

好了之后,就在ip/tftp菜单下面增加tftp文件的配置,比如说像这样:

请求文件名可以和实际文件名不一样,实际文件名是给RouterOS看的,请求文件名是给客户端看的,所以实际文件名可以自行决定。这里要主意的是ip地址填的是客户端的ip地址,而pxe服务器嘛,基本上并没有固定ip,所以ip地址最好还是填ip段。

配置就这么多,接下来只要在客户端执行pxe启动就行了。

obfs通道的部署

参考:

https://plus.google.com/+GhostAssassin/posts/bMBbFYD6JZ3
https://www.liquidweb.com/kb/how-to-install-pip-on-centos-7/

 

最近听闻了一个模糊协议,叫做obfs,是开发Tor那群人搞出来的东西,用来模糊流量避免GFW的深度包检测,我尝试了一下可以做port forward,于是顺手再搭个梯子,感觉效果似乎比shadow socks好一点(心理作用?)。

搭建过程不算太麻烦,只需要一个叫做obfsproxy的软件就可以了,在ubuntu和debian似乎可以直接安装,不过pip安装的方法更加通用。

debian系的需求包

apt-get install gcc python-pip python-dev

redhat系的需求包

yum install python-pip python-devel gcc pycrypto

其中出现了我的CentOS软件源里并没有pip这种情况,可以实用python脚本来安装,方法如下:

curl "https://bootstrap.pypa.io/get-pip.py" -o "get-pip.py"
python get-pip.py

搞定之后可以用pip来安装obfsproxy

pip install obfsproxy

安装完毕后用法如下:

服务器端:

obfsproxy --data-dir ~/.obfs/ scramblesuit --dest 127.0.0.1:1194 --password ABCDEFGHIJKLMNOPQRSTUVWXYZ234567 server 0.0.0.0:1234 &

客户端:

obfsproxy scramblesuit –dest serveraddress:1234 –password ABCDEFGHIJKLMNOPQRSTUVWXYZ234567 client 127.0.0.1:56789 &

至此通道就搭起来了,例子中,客户端访问127.0.0.1:56789就相当于在服务器端访问127.0.0.1:1194。另外要注意的就是,obfsproxy似乎并不能保证数据加密的效果,最好搭配一个更加好的加密通道来使用。

CentOS用apache当web服务器时出现的权限问题

参考:https://blog.lysender.com/2015/07/centos-7-selinux-php-apache-cannot-writeaccess-file-no-matter-what/

一般的文件读写权限,所属用户和组这些先不讨论,毕竟这些相关的文档太多,也相对基础了点。这里记录的是CentOS种由SELinux引起的权限问题。

刚在家重新搭建了owncloud,这时候出现了一个非常诡异的权限问题,文件和文件夹的所有权都是apache(CentOS中默认的所属用户和用户组),但是访问owncloud的安装程序的时候却提示没有写权限。我试过用sudo切换到apache用户来执行touch创建文件,没问题,甚至写一个简易的php脚本来测试文件的读写,都没有遇到权限的问题,但是在使用浏览器访问的时候,php脚本就遇到了权限的问题。

经过一番Google,确定时SELinux的问题。

ls -Z可以看到一些额外的属性,像这样

drwxr-xr-x. apache apache unconfined_u:object_r:httpd_sys_content_t:s0 application
-rw-r--r--. apache apache unconfined_u:object_r:httpd_sys_content_t:s0 index.php
修复的办法是
# SELinux serve files off Apache, resursive
sudo chcon -t httpd_sys_content_t /data/www/html/sites/mysite -R
# Allow write only to specific dirs
sudo chcon -t httpd_sys_rw_content_t /data/www/html/sites/mysite/logs -R
sudo chcon -t httpd_sys_rw_content_t /data/www/html/sites/mysite/uploads -R

httpd_sys_content_t – 允许apache读取文档
httpd_sys_rw_content_t – 允许apache读写文档
更加详细的标记说明,可以参考https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Managing_Confined_Services/sect-Managing_Confined_Services-The_Apache_HTTP_Server-Types.html

在RouterOS上启用基于域名的策略路由

最近在折腾RouterOS,发现了一种相当有趣的用法,可以基于域名来选择路由。
首先,在ip/firewall/address lists中添加地址,地址可以是ip地址或者是域名,如果是域名,则RouterOS会自动进行一次域名解析,例如这样:
ip.firewall.addresslist
可以看到域名被自动解析成了ip地址,而解析出来的记录前面有个D标记,这意味着这是动态的,ip地址记录会随着dns解析记录而变更。

例子中,我就创建了一个叫做twitter.com的address list,这就可以在mangle中做点手脚了,就像这样:

我在prerouting链中添加了一个mangle,对目标地址在twitter.com列表中的路由都进行一个标记,打上一个叫做gfw的路由标记,在打上标记之后呢,就可以在路由表中,添加一个新的路由:

例子中,我有一个名字叫做gfw的接口,作用就不多说,因为是一个ppp的链接,所以gateway可以不填地址,直接填一个接口的名字,RouterOS可以处理这种情况。上图中,就是说所有打着gfw标记的路由,默认路由是走gfw这个接口。至此,全部基本设置已经完成。

这种addresslist配合mangle的用法除了策略路由还有很多其他的用法,比如说想要屏蔽某些网站,不让用户访问,这就可以在route中,选择这个unreachable的类型,这可比用web-proxy什么的实用多了,屏蔽掉的就不仅仅是80端口了,而是整个ip,无论是http还是https或者其他协议之类的,都会屏蔽掉。当然,在一些比较精细的控制方面,比如说允许访问http://www.helloworld.com但是不允许访问http://www.helloworld.com/something这种就无能为力了,只能向L7方面寻求帮助。


这种方法还有类似的,比如说传统一点,在address lists中,不用域名,而是用地址块,比如说这样:

把一整块地址加进去address lists里面,也是可以的,这样更加容易绕开方法里面的一种缺陷,因为这种方法只能对应一个域名,无法处理子域名或者使用通配符,如果是大量的域名,这会让工作变得相当的麻烦,需要脚本来进行处理。

这种方法有另外一种缺陷,就是面对着同一个域名会有大量ip地址或者是使用CDN网络的网站的时候,容易出问题,RouterOS本身缓存的dns解析地址一般来说只有2条,如果客户端使用了其他dns服务器而不是RouterOS本身作为DNS服务器的话有可能会存在这样一种情况:

RouterOS解析域名A,得到ip地址1ip地址2,并对ip地址1ip地址2进行了策略路由,客户端从dns服务器解析域名A,得到ip地址3ip地址4,这种情况下,客户端访问域名A就没法得到正确的策略路由。

对应的方法很简单,只要指定RouterOS作为客户端的dns服务器就可以了。如果是有客户端想使用其他dns服务器绕过策略路由,可以使用dnat进行劫持,如果是使用dnscrypt之类的软件的话,似乎没什么好对策,毕竟就算是gfw也只能阻挡而不能污染或者劫持dnscrypt。