Wireguard:修订间差异

来自牛奶河Wiki
跳到导航 跳到搜索
 
(未显示同一用户的6个中间版本)
第2行: 第2行:


=== 服务端 ===
=== 服务端 ===
0. Sys Conf
==== sysctl ====
  # /etc/sysctl.conf
  # /etc/sysctl.conf
  net.ipv4.ip_forward = 1
  net.ipv4.ip_forward = 1


==== wireguard ====
==== wireguard ====
apt install openresolv
  apt install wireguard
  apt install wireguard
2. 生成秘钥对
 
==== 生成秘钥对 ====
  wg genkey | tee server_privatekey | wg pubkey > server_publickey
  wg genkey | tee server_privatekey | wg pubkey > server_publickey
  wg genkey | tee u01_privatekey | wg pubkey > u01_publickey
  wg genkey | tee u01_privatekey | wg pubkey > u01_publickey
  wg genkey | tee u02_privatekey | wg pubkey > u02_publickey
  wg genkey | tee u02_privatekey | wg pubkey > u02_publickey
3. 配置文件生成
==== 服务配置 ====
==== 服务配置 ====
  <small><nowiki># Server: /etc/wireguard/wg0.conf
  <small><nowiki># Server: /etc/wireguard/wg0.conf
第61行: 第61行:
客户端导入此文件或扫描此文件生成的二维码即可。
客户端导入此文件或扫描此文件生成的二维码即可。
  # apt install qrencode
  # apt install qrencode
  # 在 Linux ssh 窗口中显示二维码
  # 生成二维码
  cat u01.conf | qrencode -o - -t UTF8
  cat u01.conf | qrencode -o - -t UTF8 # 命令行窗口显示
cat u01.conf | qrencode -o u01.png    # 生成图片


==== 启动 ====
==== 启动 ====
第90行: 第91行:
=== 客户端 ===
=== 客户端 ===
[https://www.wireguard.com/install/ Windows 下载](Mac/IOS 从 App Store 下载) wireguard,扫描二维码或导入从服务端创建的客户端文件即可。
[https://www.wireguard.com/install/ Windows 下载](Mac/IOS 从 App Store 下载) wireguard,扫描二维码或导入从服务端创建的客户端文件即可。
Ubuntu 安装:
apt install wireguard
# 将客户端文件 u01.conf 拷贝至 /etc/wireguard
wg-quick up u01
若服务端修改了端口,客户端在配置中只需要修改端口重起即可。
=== QR ===
使用 qrcode.min.js 可以在网页上生成二维码。
<small><nowiki><html>
<head>
<title>Javascript QRCode</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script type="text/javascript" src="/js/qrcode.min.js"></script>
</head>
<body>
<input id="text" type="text" value="u01" style="width:250" />
<button onclick="makeCode()">QR</button>
<div id="qrcode" style="width:300px; height:300px; margin-top:10px;"></div>
<script type="text/javascript">
var qrcode = new QRCode(document.getElementById("qrcode"), {
width : 300,
height: 300
});
function makeCode() {
    var fileName = document.getElementById("text").value;
    var filePath = `QR/${fileName}.conf`;
    fetch(filePath)
        .then(response => {
            if (!response.ok) {
                throw new Error('File not found');
            }
            return response.text();
        })
        .then(data => {
            qrcode.makeCode(data);
        })
        .catch(error => {
            if (error.message === 'File not found') {
                qrcode.makeCode(fileName);
            } else {
                console.error('Error reading file:', error);
                alert('ER');
            }
        });
}
makeCode();
</script>
</body>
</html></nowiki></small>
=== 通过网页修改服务端口 ===
# 通过 php,修改 wg0.conf(调整文件权限或归属)
# 如果无法直接修改 wg0.conf 文件,如:wireguard 与 web 分属两台主机。则可以通过 shell 将文件同步,并重启服务
# PHP in web server
<small><nowiki><?php
$file_path = '/etc/sync/wg0.conf';
$key = 'ListenPort = ';
$error = '';
$message = '';
$listen_port = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if (isset($_POST['listenPort']) && is_numeric($_POST['listenPort'])) {
        $new_port = intval($_POST['listenPort']);
        try {
            $content = file_get_contents($file_path);
            if ($content === false) {
                throw new Exception('Failed to read the file.');
            }
            $pattern = '/' . preg_quote($key, '/') . '\d+/';
            $replacement = $key . $new_port;
            $updated_content = preg_replace($pattern, $replacement, $content);
            if ($updated_content === null) {
                throw new Exception('Failed to update the file content.');
            }
            if (file_put_contents($file_path, $updated_content) === false) {
                throw new Exception('Failed to write to the file.');
            }
            $message = 'File updated successfully!';
        } catch (Exception $e) {
            $error = $e->getMessage();
        }
    } else {
        $error = 'Invalid ListenPort value.';
    }
}
try {
    $content = file_get_contents($file_path);
    if ($content === false) {
        throw new Exception('Failed to read the file.');
    }
    $pattern = '/' . preg_quote($key, '/') . '(\d+)/';
    if (preg_match($pattern, $content, $matches)) {
        $listen_port = $matches[1];
    } else {
        throw new Exception('ListenPort not found in the file.');
    }
} catch (Exception $e) {
    $error = $e->getMessage();
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Edit ListenPort</title>
</head>
<body>
    <h1>Modify ListenPort</h1>
    <?php if ($error): ?>
        <p style="color: red;"><?php echo htmlspecialchars($error); ?></p>
    <?php endif; ?>
    <?php if ($message): ?>
        <p style="color: green;"><?php echo htmlspecialchars($message); ?></p>
    <?php endif; ?>
    <form method="POST">
        <label for="listenPort">ListenPort:</label>
        <input type="text" id="listenPort" name="listenPort" value="<?php echo htmlspecialchars($listen_port); ?>" required>
        <button type="submit">Submit</button>
    </form>
</body>
</html></nowiki></small>
# Shell in wireguard server
<small><nowiki>#!/bin/bash
export PATH=$PATH:/sbin:/usr/sbin
TIMEID=`date '+%Y/%m/%d %H:%M:%S'`
src="root@mc3:/etc/sync/wg0.conf"
dest="/etc/wireguard/wg0.conf"
rsync -a $src $dest
v1=`md5sum ${dest} | awk -F' ' '{print $1}'`
v2=`md5sum ${dest}.bak | awk -F' ' '{print $1}'`
if [ "$v1" == "$v2" ];then
    echo $TIMEID 'The file has not changed.'
else
    echo $TIMEID 'The file has changed, restart wg0.'
    cp $dest ${dest}.bak
    cd /etc/wireguard
    wg-quick down wg0
    wg-quick up wg0
fi</nowiki></small>


=== Error ===
=== Error ===
第97行: 第259行:
==== resolvconf: command not found ====
==== resolvconf: command not found ====
  /usr/bin/wg-quick: line 32: resolvconf: command not found
  /usr/bin/wg-quick: line 32: resolvconf: command not found
  如果是在 shell 里执行命令,一般在 .bash_profile, .bashrc 等文件中的环境变量不会带进来,需要执行 source ~/.bashrc 等命令。或者:
  1. apt install openresolv
export PATH=$PATH:/sbin:/usr/sbin  # resolvconf 在 /usr/sbin
2. 如果是在 shell 里执行命令,一般在 .bash_profile, .bashrc 等文件中的环境变量不会带进来,需要执行 source ~/.bashrc 等命令。或者:
    export PATH=$PATH:/sbin:/usr/sbin  # resolvconf 在 /usr/sbin


[[分类:Develop]]
[[分类:Develop]]
[[分类:Platform]]
[[分类:Platform]]
[[分类:Linux]]
[[分类:Linux]]

2025年1月14日 (二) 23:24的最新版本

WireGuard 是一种实现加密虚拟专用网络(VPN)的通信协议和免费开源软件,通过 UDP 传递流量,旨在比 IPsec 和 OpenVPN 这两种常见的隧道协议具有更好的性能和更强大的功能,其设计目标是易于使用、高速性能和低攻击面;

服务端

sysctl

# /etc/sysctl.conf
net.ipv4.ip_forward = 1

wireguard

apt install openresolv
apt install wireguard

生成秘钥对

wg genkey | tee server_privatekey | wg pubkey > server_publickey
wg genkey | tee u01_privatekey | wg pubkey > u01_publickey
wg genkey | tee u02_privatekey | wg pubkey > u02_publickey

服务配置

# Server: /etc/wireguard/wg0.conf
serverip=$(curl ipv4.icanhazip.com)
port=17731
eth=$(ls /sys/class/net | awk '/^e/{print}')
wg0=$(cat server_publickey)
wg0p=$(cat server_privatekey)
u01=$(cat u01_publickey)
u02=$(cat u02_publickey)
u01p=$(cat u01_privatekey)
u02p=$(cat u02_privatekey)

cat > wg0.conf <<-EOF
[Interface]
PrivateKey = $wg0p
Address = 10.0.0.1/32
PostUp   = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o $eth -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o $eth -j MASQUERADE
ListenPort = $port
DNS = 8.8.8.8
MTU = 1420

[Peer]
PublicKey = $u01
AllowedIPs = 10.0.0.10/32
[Peer]
PublicKey = $u02
AllowedIPs = 10.0.0.20/32
EOF

连接配置

# Client: /etc/wireguard/u01.conf
cat > u01.conf <<-EOF
[Interface]
PrivateKey = $u01p
Address = 10.0.0.10/24
DNS = 8.8.8.8
MTU = 1420

[Peer]
PublicKey = $wg0
Endpoint = $serverip:$port
AllowedIPs = 0.0.0.0/0, ::0/0
PersistentKeepalive = 25
EOF

客户端导入此文件或扫描此文件生成的二维码即可。

# apt install qrencode
# 生成二维码
cat u01.conf | qrencode -o - -t UTF8  # 命令行窗口显示
cat u01.conf | qrencode -o u01.png    # 生成图片

启动

wg-quick up wg0
# shutdown
wg-quick down wg0
# status
wg

配置启动服务(可选)

# systemctl start wireguard
# /etc/init.d/wireguard
#!/bin/bash
### BEGIN INIT INFO
# Provides:		wgstart
# Required-Start:	$remote_fs $syslog
# Required-Stop:    $remote_fs $syslog
# Default-Start:	2 3 4 5
# Default-Stop:		0 1 6
# Short-Description:	wireguard
### END INIT INFO
wg-quick up wg0

chmod +x /etc/init.d/wireguard
cd /etc/init.d
update-rc.d wireguard defaults

客户端

Windows 下载(Mac/IOS 从 App Store 下载) wireguard,扫描二维码或导入从服务端创建的客户端文件即可。

Ubuntu 安装:

apt install wireguard
# 将客户端文件 u01.conf 拷贝至 /etc/wireguard
wg-quick up u01

若服务端修改了端口,客户端在配置中只需要修改端口重起即可。

QR

使用 qrcode.min.js 可以在网页上生成二维码。

<html>
<head>
<title>Javascript QRCode</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script type="text/javascript" src="/js/qrcode.min.js"></script>
</head>
<body>
<input id="text" type="text" value="u01" style="width:250" />
<button onclick="makeCode()">QR</button>
<div id="qrcode" style="width:300px; height:300px; margin-top:10px;"></div>

<script type="text/javascript">
var qrcode = new QRCode(document.getElementById("qrcode"), {
	width : 300,
	height: 300
});

function makeCode() {
    var fileName = document.getElementById("text").value;
    var filePath = `QR/${fileName}.conf`;

    fetch(filePath)
        .then(response => {
            if (!response.ok) {
                throw new Error('File not found');
            }
            return response.text();
        })
        .then(data => {
            qrcode.makeCode(data);
        })
        .catch(error => {
            if (error.message === 'File not found') {
                qrcode.makeCode(fileName);
            } else {
                console.error('Error reading file:', error);
                alert('ER');
            }
        });
}

makeCode();

</script>
</body>
</html>

通过网页修改服务端口

  1. 通过 php,修改 wg0.conf(调整文件权限或归属)
  2. 如果无法直接修改 wg0.conf 文件,如:wireguard 与 web 分属两台主机。则可以通过 shell 将文件同步,并重启服务
# PHP in web server
<?php
$file_path = '/etc/sync/wg0.conf';
$key = 'ListenPort = ';

$error = '';
$message = '';
$listen_port = '';

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if (isset($_POST['listenPort']) && is_numeric($_POST['listenPort'])) {
        $new_port = intval($_POST['listenPort']);
        try {
            $content = file_get_contents($file_path);
            if ($content === false) {
                throw new Exception('Failed to read the file.');
            }

            $pattern = '/' . preg_quote($key, '/') . '\d+/';
            $replacement = $key . $new_port;
            $updated_content = preg_replace($pattern, $replacement, $content);

            if ($updated_content === null) {
                throw new Exception('Failed to update the file content.');
            }

            if (file_put_contents($file_path, $updated_content) === false) {
                throw new Exception('Failed to write to the file.');
            }

            $message = 'File updated successfully!';
        } catch (Exception $e) {
            $error = $e->getMessage();
        }
    } else {
        $error = 'Invalid ListenPort value.';
    }
}

try {
    $content = file_get_contents($file_path);
    if ($content === false) {
        throw new Exception('Failed to read the file.');
    }

    $pattern = '/' . preg_quote($key, '/') . '(\d+)/';
    if (preg_match($pattern, $content, $matches)) {
        $listen_port = $matches[1];
    } else {
        throw new Exception('ListenPort not found in the file.');
    }
} catch (Exception $e) {
    $error = $e->getMessage();
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Edit ListenPort</title>
</head>
<body>
    <h1>Modify ListenPort</h1>
    <?php if ($error): ?>
        <p style="color: red;"><?php echo htmlspecialchars($error); ?></p>
    <?php endif; ?>
    <?php if ($message): ?>
        <p style="color: green;"><?php echo htmlspecialchars($message); ?></p>
    <?php endif; ?>

    <form method="POST">
        <label for="listenPort">ListenPort:</label>
        <input type="text" id="listenPort" name="listenPort" value="<?php echo htmlspecialchars($listen_port); ?>" required>
        <button type="submit">Submit</button>
    </form>
</body>
</html>
# Shell in wireguard server
#!/bin/bash
export PATH=$PATH:/sbin:/usr/sbin

TIMEID=`date '+%Y/%m/%d %H:%M:%S'`

src="root@mc3:/etc/sync/wg0.conf"
dest="/etc/wireguard/wg0.conf"

rsync -a $src $dest

v1=`md5sum ${dest} | awk -F' ' '{print $1}'`
v2=`md5sum ${dest}.bak | awk -F' ' '{print $1}'`

if [ "$v1" == "$v2" ];then
    echo $TIMEID 'The file has not changed.'
else
    echo $TIMEID 'The file has changed, restart wg0.'
    cp $dest ${dest}.bak
    cd /etc/wireguard
    wg-quick down wg0
    wg-quick up wg0
fi

Error

Warning: ?? is world accessible

This means that the configuration file permissions are too broad - and they shouldn’t, as there’s a private key in there. This can be fixed with

chmod 600 /etc/wireguard/wg0.conf

resolvconf: command not found

/usr/bin/wg-quick: line 32: resolvconf: command not found
1. apt install openresolv
2. 如果是在 shell 里执行命令,一般在 .bash_profile, .bashrc 等文件中的环境变量不会带进来,需要执行 source ~/.bashrc 等命令。或者:
   export PATH=$PATH:/sbin:/usr/sbin   # resolvconf 在 /usr/sbin