JanBox的小站 Exit Reader Mode

折腾着实验室的服务器

实验室总有那么一台电脑没人用,于是开启了折腾之路。

平时打比赛需要断网,但有时候实现不了,所以打算拿它做个路由,再加上学校在去年接入了CERNET2,能用IPv6,作为学校可能是最先进的实验室(胡说……,那一定要改造啦。

配置

i3 四代 + 4G + WD1T
板载1000/100/10网卡 + 100/10 PCI网卡 + Tp-Link 1000/100/10 PCIE网卡
没有组RAID 嗯,别出事就好,学校OJ曾经挂过,然后ZOJ 说是组了RAID5 结果挂了两块硬盘(那还不如多备份呢~~

需求(其实要啥有啥……

IPv4路由,DNS,IPv6子网转发,samba共享,git服务器,fprc ……

综述

选了Ubuntu Server 16.04 LTS 作为服务器的操作系统,然后IPv4路由选用iptables 进行转发,DNS用BIND9 可以同时解析IPv6和IPv4的请求,IPv6那部分用了ndppd和radvd以及dhcp6实现,IPv4DHCP选择了isc-dhcp-driver 来实现,frpc就是一个内网穿透,Github上的一个开源项目,试了一下,觉得挺好的,原理就不说了,Github的wiki上有这部分的解释。

step by step

硬件配置(也就只有网卡好讲的……

板载的1000/100/10MBps 的用作IPv6的接入,以后其实可以用python 进行校园网认证的,然后,再用bond mod 5或mod 6 来实现负载均衡?有了解的可以留个言互相学习呗

PCI 100/10MBps 用作IPv4 的接入 , 本来也就只有100Mbps,刚刚好就行

PCIE 1000/100/10Mbps 用作实验室内网的接入,连接着五口的千兆交换机,然后再下行给一台中兴的16口百兆和H3C的24口千兆交换机,有可能做共享服务器,高速还是很有必要的,而且负载均衡实现了之后大概可以有150+M的带宽吧……

IPv4 路由

考虑以后可能可以用来做其它的事,以及整个实验室的设备都要通过这个服务器获取IP,所以就用了B类的私有IP 范围从172.16.10.0 – 172.16.239.255,保留前10*255个ip用于以后如果有需求就可以接入新的服务器并在同个网段内。由于在某些情况下需要断网,只允许内部机器访问,所以还是采用iptables 做限制好了
(坑待填……

DNS

bind9 就好了,不设置转发,所有的请求由服务器向根域名服务器请求并向下查询,虽然慢了点,但还是还是比较有保证不被污染吧(也许……
ipv6 的话也一起用bind9 查询好了(就酱……
至于那几个自己的OJ我还是手写解析吧,这样断网还可以打比赛,刚刚想到其实可以做污染的,在打比赛的时候,结束后重新更新一下就好了(大雾……

12/03/2017更

递归查询果然很慢……,还容易被污染,国内现在连IPv6 也污染,就只能把一些被墙了的地址放在 bind 的转发区里,这些地址由服务器走IPv6 向谷歌的DNS 查,在bind的config 里加一句

zone "example.com" { type forward; forwarders { 2001:4860:4860::8888; 2001:4860:4860::8844; }; }; 

后面两个 地址是谷歌的DNS 做了多播,所以国内访问的是应该香港的节点, 谷歌的每一个服务器好像都是全能的,example.com 则是国内墙了的域名,这个方法只能解决域名在IPv4环境下被封杀的问题,所以谷歌还是可以上的
然后还用了 nscd 来缓存DNS 查询记录,就只开启hosts 和 services 的功能而已,我自己设定是成功保存 900s,失败保存5s,有些失败可能是网络波动引起的,然后也不想继续递归查询了,教育完的IPv6优化的很差,虽说是与HE.net互联(好像还有与hkix网,美国的Internet2 网络等互联,但大部分流量好像还是走He的线路),但是并没有多好,不知道是谁的锅。

IPv6

拿着isc dhcp server 组了一个池,以为需要手写init.d里的脚本,实际上发现好像直接就能用了,写了一个conf 配置文件,主要内容百度都有,这个其实还是挺简单的,之前网上看到的版本都说得手写init.d 的脚本并把它加到服务里,现在的新版好像不用了,然后用着radvd 做网内广播,也是很普遍的脚本,我用了一个/80 的前缀,之前是打算用一个/64 的前缀,让内网的机器直接计算就好了,但那样问题好像还挺多,比如路由表…,一直转发到那个不能用的IPv6的网卡上,很奇怪……也不会删那条记录……用npddp做广播字段,怎么写conf文件,去谷歌吧,国内这部分资料相当不全。记得npddp 是GitHub上的一个项目来着,但是现在巨迷……只有我的电脑能使用IPv6,其它的Linux都不能,查了一下,说是可能IPv6的地址没广播出去,ndppd是用过NDP(邻居发现协议),来确定要广播哪些IP在此子网中,试着把某个IPv6加入到服务器邻居中,但还是不行,可能得等一段时间才会生效,能用IPv6 的那台是Win ,其他的都是Ubuntu 做了一下包跟踪,发现,出了网关之后包就丢失了,ping的结果是找不到主机,但是能上的那台,则没有任何问题,可能还得去看下ipv6的一些协议,也确实,那些通过dhcpv6获得IP的并不在软路由的邻居中,这方面再去了解一下好了,然后学校实际的ipv6带宽并不是很高,自己的服务器上常备100M的测试包,ipv4 下载能在4-5M左右,而ipv6 的测试也就1-2,继续研究中……

06/01/2017更)实验室的突然全网不能使用ipv6,不知道为什么,觉得是没发现邻居,那只好等着用一个/64的网段来实验室内用了(试试???)反正绝对不会用什么nat的(也说不定Orz……!
12/03/2017 最终妥协用了NAT 实验室内的子网对外只是一个IP,之所以没办法直接用一个/64 网段可能是因为外界的路由的原因Orz,然后好像DNS 也重新配置了一下见上……

frpc

github上的开源项目,拿go写的,很好用其实,可以去看看,给出了很详细的说明,可能得自己手写init.d。 在自己有公网IP的服务器上安装frps 服务端,然后在github上找到了一个init.d 的系统服务脚本,有空把它贴上来好了,自己的服务器在日本,教育网走国外的又是先到美国再各处分发,结果那延迟惨不忍睹…………打算在阿里云什么的申请一台服务器好了
脚本在这里,这是客户端的,服务端也一样,看着改就好了

#! /bin/bash
# chkconfig: 2345 55 25
# Provides:          frpc
# Required-Start:    $all
# Required-Stop:     $all
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: starts the frpc
# Description:       starts frpc using start-stop

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
ProgramName="Frpc" #看着改
ProgramPath="/usr/local/bin/frpc" #看着改
NAME=frpc #看着改
BIN=${ProgramPath}/${NAME}
CONFIGFILE=${ProgramPath}/frpc.ini
SCRIPTNAME=/etc/init.d/${NAME}


fun_check_run(){
    PID=`ps -ef | grep -v grep | grep -i "${BIN}" | awk '{print $2}'`
    if [ ! -z $PID ]; then
        return 0
    else
        return 1
    fi
}
fun_load_config(){
    if [ ! -r ${CONFIGFILE} ]; then
        echo "config file ${CONFIGFILE} not found"
        return 1
    fi
}
fun_start()
{
    if fun_check_run; then
        echo "${ProgramName} (pid $PID) already running."
        return 0
    fi
    fun_load_config
    echo -n "Starting ${ProgramName}(${program_version})..."
    ${BIN} -c ${CONFIGFILE} >/dev/null 2>&1 &
    sleep 1
    if ! fun_check_run; then
        echo "start failed"
        return 1
    fi
    echo " done"
    echo "${ProgramName} (pid $PID)is running."
    return 0
}
fun_stop(){
    if fun_check_run; then
        echo -n "Stoping ${ProgramName} (pid $PID)... "
        kill $PID
        if [ "$?" != 0 ] ; then
            echo " failed"
            return 1
        else
            echo " done"
        fi
    else
        echo "${ProgramName} is not running."
    fi
    return 0
}
fun_restart(){
    fun_stop
    fun_start
}
fun_status(){
    PID=`ps -ef | grep -v grep | grep -i "${BIN}" | awk '{print $2}'`
    if [ ! -z $PID ]; then
        echo "${ProgramName} (pid $PID) is running..."
    else
        echo "${ProgramName} is stopped"
        exit 0
    fi
}
checkos(){
    if grep -Eqi "CentOS" /etc/issue || grep -Eq "CentOS" /etc/*-release; then
        OS=CentOS
    elif grep -Eqi "Debian" /etc/issue || grep -Eq "Debian" /etc/*-release; then
        OS=Debian
    elif grep -Eqi "Ubuntu" /etc/issue || grep -Eq "Ubuntu" /etc/*-release; then
        OS=Ubuntu
    elif grep -Eqi "Alpine" /etc/issue || grep -Eq "Alpine" /etc/*-release; then
        OS=Alpine
    else
        echo "Not support OS, Please reinstall OS and retry!"
        return 1
    fi
}
fun_config(){
    if [ -s ${CONFIGFILE} ]; then
        vi ${CONFIGFILE}
    else
        echo "${ProgramName} configuration file not found!"
        return 1
    fi
}
fun_version(){
    echo "${ProgramName} version ${program_version}"
    return 0
}
fun_help(){
    ${BIN} --help
    return 0
}

arg1=$1
[  -z ${arg1} ]
case "${arg1}" in
    start|stop|restart|status|config)
        fun_${arg1}
    ;;
esac
exit $RET_VAL

IPv4路由

开启内核转发后,用iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE 一句话搞定,然后打比赛的时候…… 直接劫持目的地 iptables -t nat -I PREROUTING -p tcp -o eth0 -j DNAT –to-destination 0.0.0.0 把所有的tcp请求,都转发到0.0.0.0 这台机子上,这样的话,你什么梯子啊,什么的都不行,其实更好应该是封了所有的端口,只允许某些目的地端口的请求,再将这几个端口的数据包的目的地强制改变,这样的话,运行的udp下的dns什么的还能正常工作吧……,一般也没人用udp 做梯子吧??最终还是只用了tcp的拦截,上面的iptable可能描述有些不准确,详细的看iptables -help 吧

05/08 更新

仔细了解了一下IPtables 之后 决定不用nat 表修改,nat 表全部放行,但在filter 表的forward 链中详细按端口来控制访问权限,最先先把forward 链用 iptables -P FORWARD DROP 默认设为DROP 然后再添加放行规则,比如我允许 0.0.0.0 的80端口与内网的计算机交互,那么我就可以用以下命令

iptables -I FORWARD -d 0.0.0.0 -p tcp --dport 80 -j ACCEPT
iptables -I FORWARD -s 0.0.0.0 -p tcp --sport 80 -j ACCEPT

第一条是允许内转发到外
第二条是允许外转发到内
之所以这样改,还是以防万一把~~~

git

实验室可能就用来放点代码什么的,但是发现还是挺麻烦的,所以觉得还是做远程仓库的备份好了,直接git clone 等有空写个脚本好了~

samba

文件共享什么的最好了,用的是samba ,毕竟实验室内还是有windows的存在的,直接安装就好了,其实本来是想做成ftp的,但发现用vsftpd有点不会配置,所以还是先做了文件共享,速度还可以,基本能到硬盘的极限速度,也差不多就是千兆了,这样可能网速会受到一些影响,然后肯定是做权限严格区分的,只有实验室的人拥有账号才可以上传,但所有人都可以访问,ftp的话肯定也要严格权限啊!!

(待补……

06/06更新

今天把服务器的内核更新到4.10,结果炸了,网卡全部不能识别,所有东西都不能用了,幸好没删掉原来的内核,换了回去,Emmm……可能会找时间研究下。

日志

一直很看重日志管理,毕竟能猜出来你们在干什么
主要是修改了logrote的配置,把所有的日志最少每周截取一次,并保存到/root 下的文件夹里,便于统一管理,顺便所有日志至少保存一年。
还写了个脚本,用于记录实时速度,拿ifstat 直接输出重定向一下就好了
还在打算将抓包记录写入文件,并每天晚上用个脚本自动化分析一下就好了,这样能看出顺手玩玩大数据(才不是呢……