CentOS下实现GRE over IPsec

本文IPsec部分参考 sqzhao 的CSDN 博客 ,原文地址请点击:https://blog.csdn.net/sqzhao/article/details/76093994?utm_source=copy

一、方案背景
    两台centos7服务器构建安全的VPN通道实现内网互通,IPsec接收端需要有弹性IP且安全组放通发起端的UDP500和UDP4500端口。

二、IP规划
接收端:
    IPsec地址:192.168.255.31/32,GRE地址:192.168.254.1/30
发起端:
    IPsec地址:192.168.255.28/32,GRE地址:192.168.254.2/30

三、部署IPsec
3.1、安装所需软件

yum install epel-release
yum install strongswan openssl iproute iptables


3.2、生成证书(在接收端生成,将client.cert.p12复制到发起端)

    export PUBLIC_IP=x.x.x.x   # 这里换成接收端的公网IP
    mkdir -p /usr/local/ipsec && cd /usr/local/ipsec/
    strongswan pki --gen --outform pem > ca.pem
    strongswan pki --self --in ca.pem --dn "C=CN, O=VPN, CN=strongSwan CA" --ca --lifetime 3652 \
        --outform pem > ca.cert.pem

    strongswan pki --gen --outform pem > server.pem
    strongswan pki --pub --in server.pem | strongswan pki --issue --lifetime 3652 --cacert ca.cert.pem \
        --cakey ca.pem --dn "C=CN, O=VPN, CN=${PUBLIC_IP}" --san="${PUBLIC_IP}" \
        --flag serverAuth --flag ikeIntermediate --outform pem > server.cert.pem

    strongswan pki --gen --outform pem > client.pem
    strongswan pki --pub --in client.pem | strongswan pki --issue --lifetime 3652 --cacert ca.cert.pem \
        --cakey ca.pem --dn "C=CN, O=VPN, CN=strongSwan Client" --outform pem > client.cert.pem
    openssl pkcs12 -export -inkey client.pem -in client.cert.pem -name "strongSwan Client" \
        -certfile ca.cert.pem -caname "strongSwan CA" -out client.cert.p12
    # Export Password: ###输入私钥密码,这里的密码需要配置到发起端ipsec.secrets文件里


3.3、copy证书到对应文件夹(client.cert.p12是由上一步接收端生成的,直接copy过来)

#    接收端证书
     cp -r ca.cert.pem /etc/strongswan/ipsec.d/cacerts/  
     cp -r server.cert.pem /etc/strongswan/ipsec.d/certs/  
     cp -r server.pem /etc/strongswan/ipsec.d/private/  
     cp -r client.cert.pem /etc/strongswan/ipsec.d/certs/  
     cp -r client.pem /etc/strongswan/ipsec.d/private/
#    发起端证书
     cp -r client.cert.p12 /etc/strongswan/ipsec.d/private/


3.4、接收端配置文件和密码文件

    cat >strongswan.conf <<EOF
    # strongswan.conf - strongSwan configuration file
    #
    # Refer to the strongswan.conf(5) manpage for details
    #
    # Configuration changes should be made in the included files

    charon {
        load_modular = yes
        duplicheck.enable = no
        compress = yes
        plugins {
                include strongswan.d/charon/*.conf
        }
        dns1 = 8.8.8.8
    }

    include strongswan.d/*.conf
    EOF
    cat > ipsec.conf << EOF
    # ipsec.conf - strongSwan IPsec configuration file

    # basic configuration

    config setup
        # strictcrlpolicy=yes
        uniqueids = never

    # Add connections here.

    conn %default
        left=%any
        leftsubnet=192.168.255.31/32
        right=%any
        rightsourceip=192.168.255.28/32
        dpdaction=clear

    conn IKEv2-CERT
        keyexchange=ikev2
        leftauth=pubkey
        leftcert=server.cert.pem
        rightauth=pubkey
        rightcert=client.cert.pem
        auto=start
    EOF
    cat >ipsec.secrets <<EOF
    # ipsec.secrets - strongSwan IPsec secrets file
    : RSA server.pem
    : PSK "12345678"
    stone : XAUTH "PCeva2016"
    stone : EAP “PCeva2016"
    EOF
    cp -r strongswan.conf ipsec.conf ipsec.secrets /etc/strongswan/

3.5、发起端配置文件和加密文件

    cat > strongswan.conf <<EOF
    # strongswan.conf - strongSwan configuration file
    #
    # Refer to the strongswan.conf(5) manpage for details
    #
    # Configuration changes should be made in the included files

    charon {
        load_modular = no
        plugins {
                include strongswan.d/charon/*.conf
                resolve {
                                file = /etc/resolv.conf
                }
        }
    }

    include strongswan.d/*.conf
    EOF


    cat > ipsec.conf <<EOF
    # ipsec.conf - strongSwan IPsec configuration file

    # basic configuration

    config setup
        # strictcrlpolicy=yes
        uniqueids = never

    # Add connections here.

    conn %default
        dpdaction=clear

    conn rw
        keyexchange=ikev2
        left=%any
        leftsourceip=%config
        leftauth=pubkey
        leftid="C=CN, O=VPN, CN=strongSwan Client"
        right=${PUBLIC_IP}
        rightid="C=CN, O=VPN, CN=${PUBLIC_IP}"
        rightsubnet=192.168.255.31/32
        rightauth=pubkey
        auto=start
    EOF
    cat > ipsec.secrets <<EOF
    # ipsec.secrets - strongSwan IPsec secrets file
    : P12 client.cert.p12 "admin"  # 这里的admin是3.2里输入的密码
    : PSK "12345678"
    stone : XAUTH "PCeva2016"
    stone : EAP “PCeva2016"
    EOF
    cp -f ipsec.conf ipsec.secrets strongswan.conf /etc/strongswan/

3.6、启动strongswan并检查IPsec状态

    strongswan start/restart/stop

    strongswan status
#    正常输出:
    Security Associations (1 up, 0 connecting):
      IKEv2-CERT[11]: ESTABLISHED 2 hours ago, 172.31.28.1[C=CN, O=VPN, CN=x.x.x.x]...x.x.x.x[C=CN, O=VPN, CN=strongSwan Client]
      IKEv2-CERT{40}:  INSTALLED, TUNNEL, reqid 10, ESP in UDP SPIs: cc60cb68_i c56c711e_o
      IKEv2-CERT{40}:   192.168.255.31/32 === 192.168.255.28/32

    ip address ls eth0
#    正常输出:
    2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc pfifo_fast state UP qlen 1000
        link/ether 06:b3:38:c9:2f:5f brd ff:ff:ff:ff:ff:ff
        inet 172.31.28.1/20 brd 172.31.31.255 scope global dynamic eth0
           valid_lft 2973sec preferred_lft 2973sec
        inet 192.168.255.31/32 scope global eth0
           valid_lft forever preferred_lft forever

    ping 192.168.255.28 -c 1
    ping 192.168.255.31 -c 1

四、GRE配置和路由配置(另一端的GRE配置互换IP即可)

    #!/bin/bash

    remote_ipsec=192.168.255.31
    local_ipsec=192.168.255.28

    remote_gre=192.168.254.1
    local_gre=192.168.254.2
    gre_mask=30

    remote_subnets=(172.31.0.0/16)   # 数组中每个子网用空格隔开

    strongswan status
    ping -c 1 -W 1 ${remote_ipsec} &>/dev/null
    if [ $? -eq 0 ];then
        echo ">>>ipsec ok"
        echo ">>>start add gre tunnel"

        modprobe ip_gre
        ip tunnel del tunnel0
        ip tunnel add tunnel0 mode gre remote ${remote_ipsec} local ${local_ipsec}
        ip link set tunnel0 up mtu 1400
        ip address add ${local_gre}/${gre_mask} peer ${remote_gre}/${gre_mask} dev tunnel0
    #       ip route add ${remote_subnet} via ${remote_gre} dev tunnel0

        ping -c 1 -W 1 ${remote_gre} &>/dev/null
        if [ $? -eq 0 ]; then
                echo ">>>gre tunnel ok"
        fi
    else
        echo ">>>ipsec error, exit"
        exit 1
    fi

    echo ">>>start add ip route"
    for subnet in ${remote_subnets[@]}
    do
        ip route add ${subnet} via ${remote_gre} dev tunnel0
    done

五、配置VPC路由和NAT
    VPC路由表中访问对端内网网段的路由指向本端的ECS主机
 

    隧道内的流量从tunnel0接口进来从eth0出去,转换为eth0的接口IP
    接收端NAT:
    iptables -t nat -A POSTROUTING -s 172.16.0.0/16 -o eth0 -j SNAT --to 172.18.0.1
    iptables -t nat -A POSTROUTING -s 172.17.0.0/16 -o eth0 -j SNAT --to 172.18.0.1
    发起端NAT:
    iptables -t nat -A POSTROUTING -s 172.18.0.0/16 -o eth0 -j SNAT --to 172.16.0.1

猜你喜欢

转载自blog.csdn.net/qq_27860819/article/details/82839092