🦄

OxidizedによるGitlabへのコンフィグバックアップ

2021/12/21に公開

今回はネットワーク機器のバックアップについて。
オープンソースのOxidizedを使い、オンプレのGitlabへ収納する実験。

検証環境について:

■Oxidized、並びにGitlabはVM上のDockerコンテナとして運用
■バックアップ対象は検証用のJuniper SRX

①Oxidizedの準備
Oxidized自体は簡単に設定できます。
Git: https://github.com/ytti/oxidized
Docker: https://hub.docker.com/r/oxidized/oxidized/

今回はDocker-composeによる運用を試しました。
まず、設定ファイルが必要なので、空でコンテナを立ち上げます。

mkdir /home/svc_ox/oxidized
docker run --rm -v /home/svc_ox/oxidized:/root/.config/oxidized -p 8888:8888/tcp -t oxidized/oxidized:latest oxidized

これで標的DirにOxidizedのコンフィグファイルが作成されます。

svc_ox@:~/oxidized$ ll
total 36
drwxrwxr-x 4 svc_ox svc_ox 4096 Dec 20 22:52 ./
drwxr-xr-x 8 svc_ox svc_ox 4096 Dec 20 22:14 ../
-rw-r--r-- 1 root   root   1163 Dec 20 22:21 config

コンフィグファイルは一旦放置で、後に使うSSHキーだけ用意しておきます。
尚、OpensshによるSSHキーはOxidizedが使用するRugged(Ruby関連のライブラリ)で誤作動を起こすみたいなので、PEMフォーマットでないと駄目みたいです。
https://github.com/ytti/oxidized/issues/1517

Gitlab側を用意します。

②Gitlabの設定
基本的にGitlabに対してはアクションはPushなので、別にクラウドでもいいんですが、今後CICDパイプラインでRunner等も使いたいので、コンテナとしてオンプレに設定します。
Gitlabのガイドラインに沿ってこちらもComposeとして立ち上げしました。
https://docs.gitlab.com/ee/install/docker.html
SSHのポートが既に使用されているので、そちらだけカスタムポートにしました。(2222)

web:
  image: 'gitlab/gitlab-ce:latest'
  restart: always
  hostname: 'gitlab.example.com'
  environment:
    GITLAB_OMNIBUS_CONFIG: |
      external_url 'https://gitlab.example.com'
      gitlab_rails['gitlab_shell_ssh_port'] = 2222
  ports:
    - '80:80'
    - '443:443'
    - '2222:22'
  volumes:
    - '/srv/gitlab/config:/etc/gitlab'
    - '/srv/gitlab/logs:/var/log/gitlab'
    - '/srv/gitlab/data:/var/opt/gitlab'

立ち上がったら、アクセス確認と、アカウント・リポ作成に移ります。
ちなみに、初期PWは自動で生成されるので、Shellにアクセスすることによって確認できます。

kazuma@:~$ sudo docker ps
CONTAINER ID   IMAGE                      COMMAND             CREATED        STATUS                  PORTS                                                                                                             NAMES
9d9becae50c8   gitlab/gitlab-ce:latest    "/assets/wrapper"   17 hours ago   Up 17 hours (healthy)   0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp, 0.0.0.0:2222->22/tcp, :::2222->22/tcp   kazuma_web_1

kazuma:~$ sudo docker exec -it 9d9becae50c8 bash
root@gitlab:/# cat /etc/gitlab/initial_root_password 
# WARNING: This value is valid only in the following conditions
#          1. If provided manually (either via `GITLAB_ROOT_PASSWORD` environment variable or via `gitlab_rails['initial_root_password']` setting in `gitlab.rb`, it was provided before database was seeded for the first time (usually, the first reconfigure run).
#          2. Password hasn't been changed manually, either via UI or via command line.
#
#          If the password shown here doesn't work, you must reset the admin password following https://docs.gitlab.com/ee/security/reset_user_password.html#reset-your-root-password.

Password: ***

今回はリポをdevice_configurationとし、ユーザーをsvc_oxとしました。


①の工程で作成した、SSHキーを登録しておきます。
尚、リポのURLをコピーしておいてください、次の工程で使用します。
次にOxidizedの設定を行います。

③Oxidizedの設定
Oxidizedは設定ファイルのsourceとoutputの項目によってコンフィグのバックアップを行っていきます。
デフォルトではsourceはrouter.dbというローカルファイルで、outputもローカルの指定されているDirです。
もしGitlab接続以前に検証したい方は、router.dbのみ設定するだけでバックアップの検証自体は可能です。

ちなみに、バックアップ対象の機器に設定ファイルで指定したアカウントが認証と、設定の閲覧ができるコンフィグは事前に必要です。
Juniperの場合、こういうのを簡単に用意しました。

system {
    login {
        class config_bk {
            permissions [ view view-configuration ];
        }
        user svc_ox {
            uid 2000;
            class config_bk;
            authentication {
                encrypted-password "***"; ## SECRET-DATA
            }
        }
    }

sourceであるrouter.dbはCSVフォーマットで簡潔にローカルルータの設定を登録しておきます。(DNS使ってないので、こんなんで大丈夫です)

192.168.0.30:junos:svc_ox:password

Oxidized上の設定はいじらずにこんな感じですが、場合によって手を加えてもOkです。

source:
  default: csv
  csv:
    file: "/root/.config/oxidized/router.db"
    delimiter: !ruby/regexp /:/
    map:
      name: 0
      model: 1
    gpg: false

次に、outputをGitlabに向けて、認証の部分も設定していきます。

output:
   default: git
   git:
     single_repo: true
     user: svc_ox
     email: oxidized@example.com
     repo: /root/.config/oxidized/configs.git

hooks:
  push_to_remote:
    type: githubrepo
    events: [post_store]
    remote_repo: "git@192.168.0.50:2222/svc_ox/device_configuration.git"
    publickey: "/root/.ssh/id_rsa.pub"
    privatekey: "/root/.ssh/id_rsa"

↑の場合はリポをDNSからIPにすり替えています。

終わり次第、コンテナをDocker-compposeを使って立ち上げましょう!

*** Running /etc/my_init.d/00_regen_ssh_host_keys.sh...
*** Running /etc/my_init.d/10_syslog-ng.init...
Dec 20 11:52:07 efa273836015 syslog-ng[14]: syslog-ng starting up; version='3.13.2'
*** Booting runit daemon...
*** Runit started as PID 20
Dec 20 11:52:07 efa273836015 cron[26]: (CRON) INFO (pidfile fd = 3)
Dec 20 11:52:07 efa273836015 cron[26]: (CRON) INFO (Skipping @reboot jobs -- not system startup)
I, [2021-12-20T11:52:07.686373 #27]  INFO -- : Oxidized starting, running as pid 27
I, [2021-12-20T11:52:07.687557 #27]  INFO -- : lib/oxidized/nodes.rb: Loading nodes
I, [2021-12-20T11:52:07.789349 #27]  INFO -- : lib/oxidized/nodes.rb: Loaded 1 nodes
Puma starting in single mode...
* Version 3.11.4 (ruby 2.5.1-p57), codename: Love Song
* Min threads: 0, max threads: 16
* Environment: development
* Listening on tcp://127.0.0.1:8888
Use Ctrl-C to stop

こんな感じで立ち上がってくれたら、Okです。

ちなみに、Oxidizedをコンテナで運用する場合、コンテナをStopした際にPIDのファイルが削除されず、再度立ち上げた際にこういったエラーが見られました:

*** Runit started as PID 21
A server is already running. Check /root/.config/oxidized/pid
Dec 20 10:46:16 60252663c780 cron[27]: (CRON) INFO (pidfile fd = 3)
Dec 20 10:46:16 60252663c780 cron[27]: (CRON) INFO (Running @reboot jobs)
A server is already running. Check /root/.config/oxidized/pid
A server is already running. Check /root/.config/oxidized/pid
A server is already running. Check /root/.config/oxidized/pid

https://github.com/ytti/oxidized/issues/1084
これは既知のエラーなので、再起動する場合はPIDのファイルも消してあげてくださいね。

これで一通りの準備は完了です、最後に検証していきましょう。

④検証

まず、Juniper上で設定を変更します。
ゴミコンフィグの削除をしましょう。

homelabfw01# show | compare 
[edit system services]
-    telnet;
-    xnm-clear-text;
-    web-management {
-        http {
-            interface vlan.0;
-        }
-        https {
-            system-generated-certificate;
-            interface vlan.0;
-        }
-    }
homelabfw01# commit 
commit complete

次にコンテナ上のログを確認します。

I, [2021-12-20T12:52:27.123769 #27]  INFO -- : Configuration updated for /192.168.0.30
I, [2021-12-20T12:52:27.124102 #27]  INFO -- : GithubRepo: Pushing local repository(/root/.config/oxidized/configs/config_backup.git/)...
I, [2021-12-20T12:52:27.124306 #27]  INFO -- : GithubRepo: to remote: ssh://git@192.168.0.50:2222/svc_ox/device_configuration.git

コンフィグ上で設定した[post_store]によって、Diffが発生した際に、Pushが発生するようになっています。
F5等、設定変更外でもバンバン変わってしまう機器に対しては、少し追加設定が必要かもしれません。(Rekeyとかでもアプデがかかってしまう)

GitlabでもCommitの確認ができます。

特に問題ではないのですが、Oxidizedのこちらのリポ機能はGithub用に作られているみたいで、デフォのリポ名がMasterになっています。
GitlabはデフォがMainになりますので、事前にGitlab側ですり替えておくか、Oxidizedの設定で変更する必要があります。(今回の例ではGitlab側で変更してます。)
https://docs.gitlab.com/ee/user/project/repository/branches/default.html

Oxidizedは無料で使え、コンテナサポートもばっちりしているので、コンフィグのバックアップのソリューションで悩んでる方は使ってみてはどうでしょうか?

Discussion