Skip to content

anticomputer/with-wireguard.el

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

24 Commits
 
 
 
 
 
 
 
 

Repository files navigation

with-wireguard.el: elisp library for working with wireguard network namespaces

with-wireguard.el provides primitives for managing a wireguard vpn inside a dedicated network namespace, this is useful to e.g. spawn a browser or terminal that requires access to certain network resources, without affecting any routing on main network namespace

Usage

Put with-wireguard.el in your load-path and (require 'with-wireguard)

You can start an application inside a network namespace with a given wireguard configuration using M-x with-wg-execute RET

To remove the namespace after you’re done with the application you can use the ip netns list and ip netns delete commands, respectively.

Programmatically, you can use the with-wg--deflate-ns function.

Example

My personal configuration provides an example of a simple application launcher for a wireguard network namespace, as well as a simple fetcher. All use the auto deflate flag which will automatically teardown the namespace when command exits. You’ll note how this usage pattern lets you quickly compose a collection of independently vpn’d applications, such that your system traffic is isolated at the application level rather than sharing traffic patterns and signatures as a whole.

(use-package with-wireguard
  :quelpa (with-wireguard :fetcher github :repo "anticomputer/with-wireguard.el")
  :ensure t
  :demand
  :config
  ;; these use the auto-deflate-ns toggle to automatically teardown on exit

  ;; chrome, secure core
  (defun my/with-wg-proton-secure-chrome ()
    (interactive)
    (let* ((chrome (executable-find "firejail-google-chrome"))
           (namespace
            (with-wg-execute
             "~/emacs/vpn/protonvpn/wireguard/dolores-secure.conf"
             (format "%s --no-first-run --no-default-browser-check --no-crash-upload --incognito --user-data-dir=/tmp/%s"
                     chrome (make-temp-name "chrome"))
             t)))
      (message "Spawning chrome in %s" namespace)))

  ;; xterm, fastest
  (defun my/with-wg-proton-xterm ()
    (interactive)
    (let* ((xterm (executable-find "xterm"))
          (namespace
           (with-wg-execute
            "~/emacs/vpn/protonvpn/wireguard/proton-xterm.conf"
            (format "%s" xterm) t)))
      (message "Spawning xterm in %s" namespace)))

  ;; fetcher, fastest
  (defun my/with-wg-proton-fetch (uri)
    (interactive "MFetch with wireguard (uri): ")
    (let* ((curl (executable-find "curl"))
           (namespace
            (with-wg-execute
             "~/emacs/vpn/protonvpn/wireguard/proton-fetch.conf"
             ;; wait a tiny bit for the link to init
             (format "sleep 0.5 && %s -s -O --output-dir /home/bas/Downloads -- %s"
                     curl
                     (shell-quote-argument uri))
             t)))
      (message "Spawning curl in %s" uri namespace))))

You could compose more involved state management on top of the primitives provided by with-wireguard.el but for my personal use I generally just want to spawn a single application within a given vpn, without affecting my main system network routing.

An example of direct use of the with-wg macro is provided below in the form of a vterm wireguard wrapper:

;; vterm with a wireguard namespace
(defun my/with-wg-proton-fast-vterm ()
  (interactive)
  (let* ((conf "~/emacs/vpn/protonvpn/wireguard/dolores-secure.conf")
         (ip (executable-find "ip"))
         (namespace (with-wg (conf) ns ns))
         (term
          ;; hehe
          (let ((vterm-shell
                 (format "sudo -E %s netns exec %s sudo -E -u %s zsh"
                         ip namespace (user-real-login-name))))
            (vterm))))
    (switch-to-buffer (other-buffer term))
    (switch-to-buffer-other-window term)
    (with-current-buffer term
      (setq-local with-wg--namespace namespace)
      (setq-local vterm-exit-functions
                  (append (list (lambda (proc event)
                                  (with-wg--deflate-ns
                                   with-wg--namespace)))
                          vterm-exit-functions))
      ;; set a prompt to designate this shell
      (vterm--goto-line -1)
      (vterm-send-string
       (format "[[ ! -z \"$(sudo wg)\" ]] && export PS1=\"wg-%s> \" || echo \"wireguard not active\\!\""
               (file-name-base conf)))
      (vterm-send-return))))

Licensing

This is free and unencumbered software released into the public domain.

About

Wireguard network namespace management for Emacs.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published