Rozchození VPN Wireguard na Pico W. Tento projekt umožní vytvářet třeba měřicí sondy na Picu a posílat data na server velmi bezpečným způsobem, bez velké námahy, protokolem jakým chci.
Tato implementace neumí Preshared Key Wireguardu, ale to moc nevadí.
cmake_minimum_required(VERSION 3.13)
set(PICO_BOARD pico_w)
set (CMAKE_C_STANDARD 11)
set (CMAKE_CXX_STANDARD 17)
include(pico_sdk_import.cmake)
project(PicoW C CXX ASM)
pico_sdk_init()
add_subdirectory(src/crypto)
add_executable(main
main.c
src/crypto.c
src/wireguard.c
src/wireguardif.c
src/wireguard-platform.c
src/crypto/cortex/cortex_m0_mpy121666.s
src/crypto/cortex/cortex_m0_reduce25519.s
src/crypto/cortex/mul.s
src/crypto/cortex/scalarmult.c
src/crypto/cortex/sqr.s
src/crypto/refc/blake2s.c
src/crypto/refc/chacha20.c
src/crypto/refc/chacha20poly1305.c
src/crypto/refc/poly1305-donna.c
src/crypto/refc/x25519.c
)
target_include_directories(main PRIVATE
${CMAKE_CURRENT_LIST_DIR}
${CMAKE_CURRENT_LIST_DIR}/src
)
target_link_libraries( main
pico_stdlib
pico_cyw43_arch_lwip_threadsafe_background
)
pico_enable_stdio_usb(main 1)
pico_enable_stdio_uart(main 0)
pico_add_extra_outputs(main)
#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "wireguardif.h"
#include "setupWifi.h"
#include <lwip/ip.h>
#include <lwip/ip_addr.h>
#include <lwip/netif.h>
#include <lwip/pbuf.h>
#include <lwip/udp.h>
static struct netif wg_netif_struct = {0};
static struct netif *wg_netif = NULL;
static uint8_t wireguard_peer_index = WIREGUARDIF_INVALID_INDEX;
static void wireguard_setup()
{
struct wireguardif_init_data wg;
struct wireguardif_peer peer;
// ip_addr_t ipaddr = IPADDR4_INIT_BYTES(10, 17, 19, 15); // tohle nefunguje
// ip_addr_t netmask = IPADDR4_INIT_BYTES(255, 255, 255, 0);
// ip_addr_t gateway = IPADDR4_INIT_BYTES(10, 17, 19, 1);
ip_addr_t ipaddr ;
IP4_ADDR(&ipaddr, 10, 17, 19, 15);
ip_addr_t netmask ;
IP4_ADDR(&netmask, 255, 255, 255, 0);
ip_addr_t gateway ;
IP4_ADDR(&gateway, 10, 17, 19, 1);
// Setup the WireGuard device structure
wg.private_key = "CF9VDaRuFPSa8br8UJ2QWPXi6QPJes3yzWr2w+6E+1I="; // toto je změněné, privátní klíč nebudu vystavovat na internetu
wg.listen_port = 51821;
wg.bind_netif = NULL;
// Register the new WireGuard network interface with lwIP
wg_netif = netif_add(&wg_netif_struct, &ipaddr, &netmask, &gateway, &wg, &wireguardif_init, &ip_input);
// Mark the interface as administratively up, link up flag is set automatically when peer connects
netif_set_up(wg_netif);
// Initialise the first WireGuard peer structure
wireguardif_peer_init(&peer);
peer.public_key = "Ul6rAFBsFSMGJhc1SsM2XIApIKBRj636W/nr7y8gY2U=";
peer.preshared_key = NULL;
// Allow all IPs through tunnel
// peer.allowed_ip = IPADDR4_INIT_BYTES(0, 0, 0, 0); // tohle nefunguje
// peer.allowed_mask = IPADDR4_INIT_BYTES(0, 0, 0, 0);
IP4_ADDR(&peer.allowed_ip,0,0,0,0);
IP4_ADDR(&peer.allowed_mask,0,0,0,0);
// If we know the endpoint's address can add here
// peer.endpoint_ip = IPADDR4_INIT_BYTES(46, 253, 96, 146); // tohle taky nefunguje
IP4_ADDR(&peer.endpoint_ip, 46, 253, 96, 146);
peer.endport_port = 28361;
// Register the new WireGuard peer with the netwok interface
wireguardif_add_peer(wg_netif, &peer, &wireguard_peer_index);
if ((wireguard_peer_index != WIREGUARDIF_INVALID_INDEX) && !ip_addr_isany(&peer.endpoint_ip))
{
// Start outbound connection to peer
wireguardif_connect(wg_netif, wireguard_peer_index);
}
}
int connect()
{
char ssid[] = "chorche";
char pass[] = "xxxxxxxxxxxx"; // heslo k Wifi nebudu vystavovat na Internetu
uint32_t country = CYW43_COUNTRY_CZECH_REPUBLIC;
uint32_t auth = CYW43_AUTH_WPA2_MIXED_PSK;
return setup(country, ssid, pass, auth, "MyPicoW", NULL, NULL, NULL);
}
int main()
{
stdio_init_all();
sleep_ms(10000); // pro připojení minicomu
connect();
wireguard_setup();
while( true ){
sleep_ms(500);
}
return 0;
}
/* Nastavení Wifi karty */
int setup(uint32_t country, const char *ssid, const char *pass,
uint32_t auth, const char *hostname, ip_addr_t *ip,
ip_addr_t *mask, ip_addr_t *gw)
{
if (cyw43_arch_init_with_country(country))
{
return 1;
}
cyw43_arch_enable_sta_mode();
if (hostname != NULL)
{
netif_set_hostname(netif_default, hostname);
}
if (cyw43_arch_wifi_connect_async(ssid, pass, auth))
{
return 2;
}
int flashrate = 1000;
int status = CYW43_LINK_UP + 1;
while (status >= 0 && status != CYW43_LINK_UP)
{
int new_status = cyw43_tcpip_link_status(&cyw43_state, CYW43_ITF_STA);
if (new_status != status)
{
status = new_status;
flashrate = flashrate / (status + 1);
printf("connect status: %d %d\n", status, flashrate);
}
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 1);
sleep_ms(flashrate);
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 0);
sleep_ms(flashrate);
}
if (status < 0)
{
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 0);
}
else
{
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 1);
if (ip != NULL)
{
netif_set_ipaddr(netif_default, ip);
}
if (mask != NULL)
{
netif_set_netmask(netif_default, mask);
}
if (gw != NULL)
{
netif_set_gw(netif_default, gw);
}
printf("IP: %s\n", ip4addr_ntoa(netif_ip_addr4(netif_default)));
printf("Mask: %s\n", ip4addr_ntoa(netif_ip_netmask4(netif_default)));
printf("Gateway: %s\n", ip4addr_ntoa(netif_ip_gw4(netif_default)));
printf("Host Name: %s\n", netif_get_hostname(netif_default));
}
return status;
}
Podívám se, jestli je na serveru s Wireguardem Pico vidět:
irka@vyvoj-OptiPlex-3050:~/vyuka_sspvc$ dizzy
Last login: Fri Oct 25 22:18:35 2024 from 192.168.120.228
OpenBSD 7.5 (GENERIC.MP) #82: Wed Mar 20 15:48:40 MDT 2024
Welcome to OpenBSD: The proactively secure Unix-like operating system.
Please use the sendbug(1) utility to report bugs in the system.
Before reporting a bug, please try to reproduce it with the latest
version of the code. With bug reports, please try to ensure that
enough information to reproduce the problem is enclosed, and if a
known fix for it exists, include that as well
dizzy# wg
interface: wg0
public key: Ul6rAFBsFSMGJhb0SsM2XIApIKBRj636W/nr7y8gY2U=
private key: (hidden)
listening port: 28361
peer: EOH6N6FUSuiVvUcHcyvbaXuVGdBfdDEEC9e6xLkLOWE=
endpoint: 93.99.65.6:55648
allowed ips: 10.5.0.0/24, 10.1.1.0/24, 10.17.19.7/32
latest handshake: 28 seconds ago
transfer: 374.35 KiB received, 49.04 KiB sent
peer: flhwYRnZPsS7Hxj1ux614uzeW29faXRodlWozCJGpz8= (1)
preshared key: (hidden)
endpoint: 93.99.65.6:29946
allowed ips: 10.200.1.0/24, 10.17.19.10/32
latest handshake: 56 seconds ago
transfer: 4.04 MiB received, 6.75 MiB sent
peer: wUcJro4mfAP7NdItusNifkAhxZnq4ZEu9pSXTpZpIy4= (2)
endpoint: 192.168.120.151:51821
allowed ips: 10.17.19.15/32
latest handshake: 1 minute, 25 seconds ago
transfer: 3.90 MiB received, 6.74 MiB sent
| 1 | Tady je router piskoviste.jr.lixis.cz v učebně OU5 ve škole |
| 2 | Tady je připojené moje PicoW |
PicoW je u mně v kanceláři v Jaroměři, přihlásím se na router piskoviste.jr.lixis.cz ve škole v Dobrušce a zkusím pingnout na Pico.
jirka@vyvoj-OptiPlex-3050:~$ ssh root@piskoviste.jr.lixis.cz
Last login: Sat Oct 26 01:23:11 2024 from 2a0e:5340:4:1:21e:6ff:fe42:2771
OpenBSD 7.6 (GENERIC.MP) #338: Mon Sep 30 08:55:35 MDT 2024
Welcome to OpenBSD: The proactively secure Unix-like operating system.
Please use the sendbug(1) utility to report bugs in the system.
Before reporting a bug, please try to reproduce it with the latest
version of the code. With bug reports, please try to ensure that
enough information to reproduce the problem is enclosed, and if a
known fix for it exists, include that as well.
piskoviste# ping 10.17.19.15
PING 10.17.19.15 (10.17.19.15): 56 data bytes
64 bytes from 10.17.19.15: icmp_seq=0 ttl=254 time=98.390 ms
64 bytes from 10.17.19.15: icmp_seq=1 ttl=254 time=114.618 ms
64 bytes from 10.17.19.15: icmp_seq=2 ttl=254 time=136.760 ms
64 bytes from 10.17.19.15: icmp_seq=3 ttl=254 time=158.609 ms
64 bytes from 10.17.19.15: icmp_seq=4 ttl=254 time=190.485 ms
64 bytes from 10.17.19.15: icmp_seq=5 ttl=254 time=206.880 ms
64 bytes from 10.17.19.15: icmp_seq=6 ttl=254 time=28.147 ms
64 bytes from 10.17.19.15: icmp_seq=7 ttl=254 time=53.279 ms
64 bytes from 10.17.19.15: icmp_seq=8 ttl=254 time=75.471 ms
64 bytes from 10.17.19.15: icmp_seq=9 ttl=254 time=100.860 ms
64 bytes from 10.17.19.15: icmp_seq=10 ttl=254 time=125.569 ms
64 bytes from 10.17.19.15: icmp_seq=11 ttl=254 time=156.274 ms
64 bytes from 10.17.19.15: icmp_seq=12 ttl=254 time=169.898 ms
64 bytes from 10.17.19.15: icmp_seq=13 ttl=254 time=194.776 ms
^C
--- 10.17.19.15 ping statistics ---
14 packets transmitted, 14 packets received, 0.0% packet loss
round-trip min/avg/max/std-dev = 28.147/129.287/206.880/52.265 ms
piskoviste#
Protože jsem na stejné síti, jako je i síť v Wireguardem, měl bych mít Pico W dostupné z lokálního stroje.
jirka@vyvoj-OptiPlex-3050:~$ ping 10.17.19.15
PING 10.17.19.15 (10.17.19.15) 56(84) bytes of data.
64 bytes from 10.17.19.15: icmp_seq=1 ttl=254 time=69.8 ms
64 bytes from 10.17.19.15: icmp_seq=2 ttl=254 time=91.5 ms
64 bytes from 10.17.19.15: icmp_seq=3 ttl=254 time=114 ms
64 bytes from 10.17.19.15: icmp_seq=4 ttl=254 time=136 ms
^C
--- 10.17.19.15 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3005ms
rtt min/avg/max/mdev = 69.766/102.781/136.046/24.716 ms
jirka@vyvoj-OptiPlex-3050:~$
A opět to funguje.
Závěr
Je mi úplně jedno, kde je fyzicky Pico W připojeno (myslím tím k jakému Wifi AP a jakou má svoji adresu), důležité je že je připojeno do Wireguard sítě.
Mohu na něj přistupovat, jeho IP bude vždy 10.17.19.15.
Jako vylepšení projektu se pokusím vymyslet sadu konfigurací, která bude umístěna ve flash paměti Pica (ještě tam je dost místa, protože exe soubor má do 800 kBytů).
Tim bude možno mít PicoW připojeno na různých místech, a stejně bude pořád dostupné.