Код для выделения интерфейса TUN
Вот код, который я использую для выделения интерфейса TUN:
Код: Выделить всё
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define BUFFER_SIZE 2048
int tun_alloc(char *dev) {
struct ifreq ifr;
int fd, err;
if ((fd = open("/dev/net/tun", O_RDWR)) < 0) {
perror("Opening /dev/net/tun");
return fd;
}
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
if (*dev) {
strncpy(ifr.ifr_name, dev, IFNAMSIZ);
}
if ((err = ioctl(fd, TUNSETIFF, (void *)&ifr)) < 0) {
perror("ioctl(TUNSETIFF)");
close(fd);
return err;
}
printf("Allocated interface: %s\n", ifr.ifr_name);
return fd;
}
void setup_interface(char *dev) {
struct ifreq ifr;
int sockfd;
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("Socket for interface configuration");
exit(1);
}
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, dev, IFNAMSIZ);
ifr.ifr_flags = IFF_UP | IFF_RUNNING;
if (ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0) {
perror("Bringing up interface");
close(sockfd);
exit(1);
}
printf("Brought up interface: %s\n", dev);
struct sockaddr_in *addr = (struct sockaddr_in *)&ifr.ifr_addr;
addr->sin_family = AF_INET;
inet_pton(AF_INET, "10.0.0.1", &addr->sin_addr); // IP: 10.0.0.1
if (ioctl(sockfd, SIOCSIFADDR, &ifr) < 0) {
perror("Assigning IP address");
close(sockfd);
exit(1);
}
printf("Assigned IP 10.0.0.1 to interface: %s\n", dev);
inet_pton(AF_INET, "255.255.255.0", &addr->sin_addr);
if (ioctl(sockfd, SIOCSIFNETMASK, &ifr) < 0) {
perror("Setting netmask");
close(sockfd);
exit(1);
}
printf("Set netmask 255.255.255.0 for interface: %s\n", dev);
close(sockfd);
}
void read_packets(int tun_fd) {
char buffer[BUFFER_SIZE];
ssize_t nread;
while (1) {
nread = read(tun_fd, buffer, sizeof(buffer));
if (nread < 0) {
perror("Reading from TUN interface");
close(tun_fd);
exit(1);
}
printf("Read %ld bytes from TUN\n", nread);
}
}
int main(int argc, char *argv[]) {
char tun_name[IFNAMSIZ] = "tun0";
int tun_fd;
tun_fd = tun_alloc(tun_name);
if (tun_fd < 0) {
fprintf(stderr, "Error allocating TUN interface\n");
return 1;
}
setup_interface(tun_name);
read_packets(tun_fd);
close(tun_fd);
return 0;
}
После настройки интерфейса TUN я выполнил следующие команды, чтобы включить пересылку между интерфейсами:
Код: Выделить всё
sudo sysctl -w net.ipv4.ip_forward=1
sudo iptables -t nat -A POSTROUTING -o enp4s0 -j MASQUERADE
sudo iptables -A FORWARD -i tun0 -o enp4s0 -j ACCEPT
sudo iptables -A FORWARD -i enp4s0 -o tun0 -j ACCEPT
Я проверил правильность применения конфигурации, проверив правила iptables:
Код: Выделить всё
sudo iptables -L -v -n
Код: Выделить всё
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT 0 -- tun0 enp4s0 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT 0 -- enp4s0 tun0 0.0.0.0/0 0.0.0.0/0
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Код: Выделить всё
sudo iptables -t nat -L -v -n
Код: Выделить всё
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
5 3537 MASQUERADE 0 -- \* enp4s0 0.0.0.0/0 0.0.0.0/0
Код: Выделить всё
sudo ip route show
Код: Выделить всё
default via 192.168.1.1 dev enp4s0 proto dhcp src 192.168.1.122 metric 100
10.0.0.0/24 dev tun0 proto kernel scope link src 10.0.0.1
192.168.1.0/24 dev enp4s0 proto kernel scope link src 192.168.1.122 metric 100
Код: Выделить всё
ping -I tun0 192.168.1.100
Однако пинг зависает на неопределенный срок. >
Я открыл Wireshark и ясно вижу, что пакеты ICMP отправляются через интерфейс tun0, но трафик на enp4s0 не пересылается.
Вопросы
Я подозреваю, что произошла неверная конфигурация или блокировка пересылки между интерфейсами. Я проверил журналы ядра и не обнаружил ошибок.
Или, возможно, я просто неправильно понял концепцию TUN. Пожалуйста, просветите меня!
Что может быть причиной проблемы с пересылкой между tun0 и enp4s0 и какие шаги я могу предпринять для устранения неполадок или решения этой проблемы? p>
Спасибо
Подробнее здесь: https://stackoverflow.com/questions/790 ... -interface