您现在的位置是:网站首页> 漫漫人生
让AI成为你职业生活免费助理实操
- 漫漫人生
- 2025-12-03
- 416人已阅读
让AI成为你职业生活免费助理实操

学习
生活
自媒体
编程
IT知识
AI帮助制作十字绣图
【豆包绘图】
将该图片转换为十字绣色块图,色彩数量控制在10以内,去掉噪点
...
【豆包绘图】
附件上传图片:将这个照片转为十字绣图,并给出线号
。。。
【豆包绘图】
附件上传图片:将这个照片转为十字绣图,输出十字绣图宽度控制在100像素,等比例缩放,并给出线号
。。。
【豆包绘图】
附件上传图片:将这个照片转为十字绣图,绣图绣线控制在10种,输出十字绣图宽度控制在100像素,等比例缩放,并给出线号
。。。
【豆包绘图】
附件上传图片:将这个照片转为十字绣图,绣图绣线控制在10种,尽量保持原图色,输出十字绣图宽度控制在100像素,等比例缩放,并给出线号
。。。
VPN工作原理
Q:VPN的工作原理从程序员角度讲解
A:...
Q:VPN如何接管本地的网络连接及数据传输的
A:...
VPN 要 “接管”,本质是在这个流程中插入自己的逻辑:把 “路由表指向物理网卡” 改成 “指向 VPN 虚拟网卡”,再通过虚拟网卡把流量加密后转发到 VPN 服务器
程序员视角的关键技术点(避坑 + 实现)
1.权限要求:创建虚拟网卡、修改路由表都需要 root / 管理员权限 —— 普通用户进程无法完成,所以 VPN 客户端启动时通常会提示 “请求管理员权限”;
2.跨平台差异:
Linux/Mac:直接通过 ip/route 命令或系统调用(ioctl)操作路由表和 TUN/TAP;
Windows:需要通过 WMI 或 netsh 命令修改路由,TUN/TAP 驱动需单独安装(OpenVPN 自带);
3.流量拦截的两种方式:
TUN 网卡(常用):拦截网络层的 IP 数据包,只处理 IP 协议(IPv4/IPv6),效率高;
TAP 网卡:拦截数据链路层的以太网帧,支持所有基于以太网的协议(如 ARP、DHCP),适合局域网共享 VPN;
4.断开连接后的还原:VPN 客户端关闭时,必须还原路由表和删除虚拟网卡 —— 否则电脑会 “上不了网”(所有流量还指向已消失的 tun0)。
简化代码示例(Python):模拟路由表修改和流量拦截触发
import subprocess
import pytun
def setup_vpn_tunnel(vpn_gateway, physical_gateway, vpn_server_ip):
# 1. 创建 TUN 虚拟网卡
tun = pytun.TunTapDevice(name="tun0", mode=pytun.IFF_TUN)
tun.addr = "10.8.0.2"
tun.netmask = "255.255.255.0"
tun.up()
# 2. 修改路由表(Linux 命令)
# 删除原默认路由
subprocess.run(["ip", "route", "del", "default", "via", physical_gateway])
# 添加 VPN 默认路由
subprocess.run(["ip", "route", "add", "default", "via", vpn_gateway, "dev", "tun0"])
# 访问 VPN 服务器走物理网卡(避免死循环)
subprocess.run(["ip", "route", "add", vpn_server_ip, "via", physical_gateway])
return tun
# 调用示例:VPN 网关 10.8.0.1,物理网关(路由器)192.168.1.1,VPN 服务器公网 IP 203.0.113.10
tun_device = setup_vpn_tunnel("10.8.0.1", "192.168.1.1", "203.0.113.10")
# 之后就可以从 tun_device 读取流量,加密后发送到 VPN 服务器...
Q:给个完整的VPN例子代码
A:...
前置条件
1.环境要求:Linux 系统(TUN 网卡支持最好,Windows/Mac 需额外配置驱动);
2.依赖安装:
pip install cryptography pytun # 加密库 + TUN 网卡操作库
3.权限:运行代码时需 root 权限(创建 TUN 网卡、修改路由表必须)
完整代码实现(客户端 + 服务器端)
1. 共享工具类(utils.py)
封装加密、解密、路由配置等通用功能,供客户端和服务器端调用:
import subprocess
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
import os
# 全局配置(简化:固定密钥和 IV,实际需通过密钥协商动态生成)
SECRET_KEY = b"this_is_32byte_secretkey_123456" # AES-256 需 32 字节密钥
IV_LENGTH = 12 # GCM 模式推荐 12 字节 IV(兼顾安全和性能)
TAG_LENGTH = 16 # GCM 认证标签长度(固定 16 字节)
def encrypt_data(data: bytes) -> bytes:
"""AES-GCM 加密:返回 IV + 认证标签 + 加密数据"""
iv = os.urandom(IV_LENGTH) # 每次加密生成随机 IV
cipher = Cipher(algorithms.AES(SECRET_KEY), modes.GCM(iv), backend=default_backend())
encryptor = cipher.encryptor()
ciphertext = encryptor.update(data) + encryptor.finalize()
return iv + encryptor.tag + ciphertext # 拼接格式:IV(12) + TAG(16) + CIPHERTEXT(n)
def decrypt_data(encrypted_data: bytes) -> bytes:
"""AES-GCM 解密:从拼接数据中提取 IV、标签、密文并解密"""
iv = encrypted_data[:IV_LENGTH]
tag = encrypted_data[IV_LENGTH:IV_LENGTH+TAG_LENGTH]
ciphertext = encrypted_data[IV_LENGTH+TAG_LENGTH:]
cipher = Cipher(algorithms.AES(SECRET_KEY), modes.GCM(iv, tag), backend=default_backend())
decryptor = cipher.decryptor()
return decryptor.update(ciphertext) + decryptor.finalize()
def setup_route(vpn_gateway: str, physical_gateway: str, vpn_server_ip: str):
"""Linux 路由配置:将默认路由指向 VPN 虚拟网卡,访问 VPN 服务器走物理网卡"""
try:
# 1. 删除原默认路由(假设原路由走物理网卡)
subprocess.run(
["ip", "route", "del", "default", "via", physical_gateway],
check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE
)
# 2. 添加 VPN 默认路由(所有流量走 tun0)
subprocess.run(
["ip", "route", "add", "default", "via", vpn_gateway, "dev", "tun0"],
check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE
)
# 3. 例外路由:访问 VPN 服务器公网 IP 走物理网卡(避免死循环)
subprocess.run(
["ip", "route", "add", vpn_server_ip, "via", physical_gateway],
check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE
)
print("路由配置成功!")
except subprocess.CalledProcessError as e:
print(f"路由配置失败:{e.stderr.decode()}")
raise
def cleanup_route(physical_gateway: str):
"""VPN 断开时还原路由(将默认路由切回物理网卡)"""
try:
# 删除 VPN 默认路由
subprocess.run(["ip", "route", "del", "default", "dev", "tun0"],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# 恢复原物理网卡默认路由
subprocess.run(["ip", "route", "add", "default", "via", physical_gateway],
check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print("路由还原成功!")
except subprocess.CalledProcessError as e:
print(f"路由还原失败:{e.stderr.decode()}")
2. VPN 服务器端(vpn_server.py)
功能:创建 TUN 网卡、监听 UDP 端口、接收客户端加密数据、解密后转发到公网 / 内网,再将响应加密回传给客户端。
import socket
import pytun
import threading
from utils import encrypt_data, decrypt_data
class VPNServer:
def __init__(self, tun_ip: str = "10.8.0.1", tun_netmask: str = "255.255.255.0",
listen_ip: str = "0.0.0.0", listen_port: int = 1194):
# 1. 创建 TUN 虚拟网卡(服务器端内网网关 IP:10.8.0.1)
self.tun = pytun.TunTapDevice(name="tun0", mode=pytun.IFF_TUN | pytun.IFF_NO_PI)
self.tun.addr = tun_ip
self.tun.netmask = tun_netmask
self.tun.up()
print(f"TUN 网卡创建成功:{self.tun.name}(IP:{self.tun.addr})")
# 2. 创建 UDP 套接字(监听客户端连接)
self.udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.udp_socket.bind((listen_ip, listen_port))
print(f"UDP 服务器启动:{listen_ip}:{listen_port}")
# 存储客户端地址(简化:仅支持单客户端)
self.client_addr = None
def tun_to_udp(self):
"""从 TUN 网卡读取数据(公网响应),加密后通过 UDP 发给客户端"""
while True:
try:
# 从 TUN 读取 IP 数据包(MTU 1500 字节)
ip_packet = self.tun.read(1500)
if not ip_packet or not self.client_addr:
continue
# 加密数据并发送给客户端
encrypted_data = encrypt_data(ip_packet)
self.udp_socket.sendto(encrypted_data, self.client_addr)
except Exception as e:
print(f"TUN → UDP 错误:{e}")
break
def udp_to_tun(self):
"""从 UDP 接收客户端加密数据,解密后写入 TUN 网卡(转发到公网)"""
while True:
try:
# 接收客户端数据(最大 2048 字节)
encrypted_data, addr = self.udp_socket.recvfrom(2048)
if not self.client_addr:
self.client_addr = addr # 记录第一个连接的客户端
print(f"客户端连接成功:{addr}")
# 解密数据并写入 TUN 网卡(由系统转发到公网)
ip_packet = decrypt_data(encrypted_data)
self.tun.write(ip_packet)
except Exception as e:
print(f"UDP → TUN 错误:{e}")
break
def run(self):
"""启动服务器:双线程分别处理 TUN→UDP 和 UDP→TUN"""
t1 = threading.Thread(target=self.tun_to_udp, daemon=True)
t2 = threading.Thread(target=self.udp_to_tun, daemon=True)
t1.start()
t2.start()
t1.join()
t2.join()
def cleanup(self):
"""关闭服务器时清理资源"""
self.udp_socket.close()
self.tun.down()
self.tun.delete()
print("服务器资源清理完成")
if __name__ == "__main__":
try:
# 启动 VPN 服务器(默认监听 1194 端口)
server = VPNServer()
server.run()
except KeyboardInterrupt:
print("\n服务器正在关闭...")
server.cleanup()
3. VPN 客户端(vpn_client.py)
功能:创建 TUN 网卡、配置路由、连接 VPN 服务器、将本地流量加密后发送到服务器,接收服务器响应并解密回传给本地应用。
import socket
import pytun
import threading
from utils import encrypt_data, decrypt_data, setup_route, cleanup_route
class VPNClient:
def __init__(self, tun_ip: str = "10.8.0.2", tun_netmask: str = "255.255.255.0",
vpn_server_ip: str = "203.0.113.10", vpn_server_port: int = 1194,
physical_gateway: str = "192.168.1.1"):
self.vpn_server_addr = (vpn_server_ip, vpn_server_port)
self.physical_gateway = physical_gateway # 本地路由器网关 IP(需根据实际修改)
# 1. 创建 TUN 虚拟网卡(客户端内网 IP:10.8.0.2)
self.tun = pytun.TunTapDevice(name="tun0", mode=pytun.IFF_TUN | pytun.IFF_NO_PI)
self.tun.addr = tun_ip
self.tun.netmask = tun_netmask
self.tun.up()
print(f"TUN 网卡创建成功:{self.tun.name}(IP:{self.tun.addr})")
# 2. 配置路由(接管所有流量)
setup_route(vpn_gateway="10.8.0.1", # VPN 服务器内网网关
physical_gateway=physical_gateway,
vpn_server_ip=vpn_server_ip)
# 3. 创建 UDP 套接字(连接 VPN 服务器)
self.udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
print(f"客户端准备连接 VPN 服务器:{vpn_server_ip}:{vpn_server_port}")
def tun_to_udp(self):
"""从 TUN 读取本地流量(应用发起的请求),加密后发给 VPN 服务器"""
while True:
try:
ip_packet = self.tun.read(1500)
if not ip_packet:
continue
encrypted_data = encrypt_data(ip_packet)
self.udp_socket.sendto(encrypted_data, self.vpn_server_addr)
except Exception as e:
print(f"TUN → UDP 错误:{e}")
break
def udp_to_tun(self):
"""从 UDP 接收服务器响应,解密后写入 TUN 网卡(回传给本地应用)"""
while True:
try:
encrypted_data, _ = self.udp_socket.recvfrom(2048)
ip_packet = decrypt_data(encrypted_data)
self.tun.write(ip_packet)
except Exception as e:
print(f"UDP → TUN 错误:{e}")
break
def run(self):
"""启动客户端:双线程处理流量"""
t1 = threading.Thread(target=self.tun_to_udp, daemon=True)
t2 = threading.Thread(target=self.udp_to_tun, daemon=True)
t1.start()
t2.start()
t1.join()
t2.join()
def cleanup(self):
"""关闭客户端时还原路由和清理资源"""
cleanup_route(self.physical_gateway)
self.udp_socket.close()
self.tun.down()
self.tun.delete()
print("客户端资源清理完成")
if __name__ == "__main__":
try:
# 请根据实际情况修改以下参数:
# - vpn_server_ip:VPN 服务器公网 IP(需部署在公网可访问的服务器)
# - physical_gateway:本地路由器网关(通过 `ip route` 命令查看)
client = VPNClient(
vpn_server_ip="203.0.113.10", # 替换为你的 VPN 服务器公网 IP
physical_gateway="192.168.1.1" # 替换为你的本地网关(如路由器 IP)
)
client.run()
except KeyboardInterrupt:
print("\n客户端正在关闭...")
client.cleanup()
except Exception as e:
print(f"客户端启动失败:{e}")
client.cleanup()
如何运行和测试
步骤 1:配置服务器
准备一台 公网可访问的 Linux 服务器(如阿里云、AWS 实例);
在服务器上安装依赖:pip install cryptography pytun;
上传 utils.py 和 vpn_server.py 到服务器;
用 root 权限启动服务器:
sudo python3 vpn_server.py
此时服务器会创建 tun0 网卡(IP:10.8.0.1),并监听 1194 UDP 端口。
步骤 2:配置客户端
在本地 Linux 机器上安装依赖(同上);
上传 utils.py 和 vpn_client.py 到本地;
修改 vpn_client.py 中的两个关键参数:
vpn_server_ip:替换为你的服务器公网 IP;
physical_gateway:替换为本地路由器网关(通过 ip route | grep default 查看,如 192.168.1.1);
用 root 权限启动客户端:
sudo python3 vpn_client.py
启动成功后,客户端会创建 tun0 网卡(IP:10.8.0.2)并修改路由表。
步骤 3:测试 VPN 连接
客户端启动后,打开浏览器访问 https://api.ipify.org(查询公网 IP);
若显示的是 VPN 服务器的公网 IP,说明 VPN 接管流量成功;
所有网络请求(如浏览网页、ping 命令)都会通过加密隧道传输。
核心代码解释
1.TUN 网卡操作:通过 pytun 库创建虚拟网卡,服务器和客户端的 TUN 网卡处于同一内网(10.8.0.0/24);
2.加密解密:使用 AES-256-GCM 算法,每次加密生成随机 IV,保证安全性;
3.双线程模型:客户端和服务器都用两个线程分别处理 “本地流量→加密→服务器” 和 “服务器响应→解密→本地”;
4.路由配置:客户端启动时修改默认路由,关闭时还原,避免断网。
有效的学习方法
把你要学习的资料、书籍上传给Deepseek
告诉AI:用费曼学习方法带我理解这个资料
让AI反过来提问你,二部是让你一直问
回答后,让AI指出你遗漏的地方,并帮你补充案例
如果还是不懂,就让AI换个角度
假装你是什么都不懂得小白,再解释一次
这样学下来,比死记硬背效率高太多
因为学习的关键不是“看懂”,而是“能讲出来”
上一篇:折腾折软腾硬件
下一篇:可商用的优秀开源项目收集