在 openvpn 连接上添加 iptables 路由

在 openvpn 连接上添加 iptables 路由

我的 openvpn 服务器已启动并正在运行,并且我通过 ccd 指令将某些路由推送到我的客户端,我想知道当客户端连接时如何根据 ccd 文件更新 iptables。

假设我的 client1 的 ccd 是:

ifconfig-push 10.8.0.45 255.255.255.0
push 'route 10.10.0.45'

我想将其添加到 iptables 中。

iptables -A FORWARD -s 10.8.0.45 -d 10.10.0.45 -j ACCEPT

进而

iptables -A FORWARD -s 10.8.0.0/24 -d 10.10.0.0/16 -j DROP

如果有人能指出我正确的方向,我将不胜感激,我对 bash 脚本还很陌生

答案1

你可以接入OpenVPN配置许多脚本,这些脚本从服务器接收许多参数环境变量:参见参考手册

您最感兴趣的是用于在服务器启动和关闭时插入规则的脚本up以及用于每个客户端规则的脚本。您需要修改服务器配置以包含:downDROPclient-connectclient-disconnect

# Allow user scripts
script-security 2
# up/down script
up /etc/openvpn/updown.sh
down /etc/openvpn/updown.sh
# Client connect/disconnect
client-connect /etc/openvpn/client.sh
client-disconnect /etc/openvpn/client.sh
  1. 您的/etc/openvpn/updown.sh脚本将创建一个OPENVPN并将其链接到FORWARD链中:
#!/bin/bash
IPT=/usr/sbin/iptables
# 'script_type' contains the type of the script
if [ "$script_type" = "up" ]; then
  $IPT -N OPENVPN
  $IPT -A FORWARD -j OPENVPN
  $IPT -A OPENVPN -s 10.8.0.0/24 -d 10.10.0.0/16 -j DROP
else
  $IPT -F OPENVPN
  $IPT -D FORWARD -j OPENVPN
  $IPT -X OPENVPN
fi
  1. 您的客户端脚本/etc/openvpn/client.sh将更加复杂:虽然远程客户端的公有和私有 IP 地址包含在和中ifconfig_remoteifconfig_pool_remote_ip但您需要解析 ccd 文件以找出您发送给客户端的路由:
#!/bin/bash
IPT=/usr/sbin/iptables
# We need to split the line into words as bash would, by
# interpreting the double quotes, hence the 'eval'.
function parse_ccd_line() {
  eval "local line=($1)"
  # If the first word is 'push' return the second one.
  if [ "${line[0]}" = "push" ]; then
    echo "${line[1]}"
  fi
}

# Your ccd_dir so we don't need to parse the OpenVPN
# server config file too.
ccd_dir=/etc/openvpn/ccd

if [ -f "$ccd_dir/$common_name" ]; then
  # We read the "$ccd_dir/$common_name" file line by line:
  while read line; do
    # We split the argument of every 'push' directive into 'cmd' and 'arg1'
    # If you need more arguments, the array 'push_opt' contains them.
    push_opt=($(parse_ccd_line "$line"))
    cmd=${push_opt[0]}
    arg1=${push_opt[1]}
    # We use just the 'route' commands
    if [ "$cmd" = "route" ]; then
      if [ "$script_type" = "client-connect" ]; then
        $IPT -I OPENVPN -s "$ifconfig_pool_remote_ip" -d "$arg1" -j ACCEPT
      else
        $IPT -D OPENVPN -s "$ifconfig_pool_remote_ip" -d "$arg1" -j ACCEPT
      fi
    fi
  done < "$ccd_dir/$common_name"
fi

相关内容