docker コンテナの中で OpenVPN で VPN接続する


Docker コンテナ(ubuntu系)を起動して、その中で OpenVPN を使って VPN 接続する。
CI 環境を Docker で作って GitHub Actions や Azure Pipelines で動かしたいが、社内パッケージリポジトリ、ソースリポジトリにアクセスするために VPN 接続が必要なため。

ディレクトリツリー

./
  + Dockerfile
  + docker-compose.yml
  + run.sh
  + .secrets/
    + myvpn.ovpn
    + myvpn_auth.txt

Dockerfile

FROM cimg/base:2022.03

# setup ※たぶん不要なものも入ってる
RUN sudo apt-get update \
    && sudo apt-get install -y \
    iputils-ping \
    net-tools \
    dnsutils \
    openvpn \
    rsync \
    && sudo apt clean

# openresolv のインストール
RUN wget "https://roy.marples.name/downloads/openresolv/openresolv-3.9.0.tar.xz" && \
    tar Jfx "openresolv-3.9.0.tar.xz" && \
    pushd "openresolv-3.9.0" && \
    ./configure && \
    make && \
    sudo make install && \
    popd
RUN sudo wget "https://raw.githubusercontent.com/masterkorp/openvpn-update-resolv-conf/master/update-resolv-conf.sh" -P "/etc/openvpn" && \
    sudo chmod 744 "/etc/openvpn/update-resolv-conf.sh"

docker-compose.yml

version: "2"
services:
  vpn-on-docker:
    build:
      context: ./
    volumes:
      - ./.secrets/vpn:/home/circleci/vpn
      - ./scripts:/home/circleci/scripts
    command: bash
    # command: bash ~/scripts/run.sh

run.sh

echo VPN 接続開始
sudo openvpn --config ~/vpn/myvpn.ovpn --auth-user-pass ~/vpn/myvpn_auth.txt --script-security 2 --up /etc/openvpn/update-resolv-conf.sh --down /etc/openvpn/update-resolv-conf.sh --down-pre --daemon 
sleep 5
echo VPN 接続成功

echo DNS 確認 --
cat /etc/resolv.conf
echo DNS -- 確認ここまで

echo 適当に ping --
ping <任意のVPN内ホスト> -c 5
echo -- ping ここまで

read -p "Press [Enter] key to quit."

myvpn.ovpn

OVPN 形式の設定ファイル。

myvpn_auth.txt

user
pass

を記述したテキストファイル。

使い方

docker-compose run --rm vpn-on-docker

ログ

Creating src_vpn-on-docker_run ... done
VPN 接続開始
VPN 接続成功
DNS 確認 --
# Generated by resolvconf
search myvpn-dev.local
nameserver xxx.xxx.xxx.xxx
DNS -- 確認ここまで
適当に ping --
PING myvpn-dev.local (xxx.xxx.xxx.xxx) 56(84) bytes of data.
64 bytes from myvpn-dev.local (xxx.xxx.xxx.xxx): icmp_seq=1 ttl=63 time=10.8 ms
64 bytes from myvpn-dev.local (xxx.xxx.xxx.xxx): icmp_seq=2 ttl=63 time=12.7 ms
64 bytes from myvpn-dev.local (xxx.xxx.xxx.xxx): icmp_seq=3 ttl=63 time=14.4 ms
64 bytes from myvpn-dev.local (xxx.xxx.xxx.xxx): icmp_seq=4 ttl=63 time=12.3 ms
64 bytes from myvpn-dev.local (xxx.xxx.xxx.xxx): icmp_seq=5 ttl=63 time=14.1 ms

--- myvpn-dev.local ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4026ms
rtt min/avg/max/mdev = 10.759/12.856/14.365/1.307 ms
-- ping ここまで
Press [Enter] key to quit.

こんな感じで繋がるはず。

メモ

  • Ubuntu の生イメージじゃなくて CircleCI が提供する便利イメージを使っている(が、それに依存する箇所は特にない)
  • 弊社の VPN では接続時に DNS が配布されるようだが、それを適用するために openresolv が必要だった
  • ./secrets は取扱注意。
    • myvpn_auth.txt は 1行目ユーザー、2行目パスワードを遵守しないと "Enter password:" のプロンプトが出る。

Ref