Vyos - Between Rolling Releases, Stability and Security

The following article introduces the reader to the deployment of the network appliance VyOS with the help of Continuous Integration & Deployment processes. The main goal is to control the full life cycle of an open source firewall and router, starting from the creation of the install/update iso image.

What is VyOS?

VyOS is an open source network operating system based on Debian GNU/Linux.

With the help of Gitlab CI/CD we will semi-automatically generate a VyOS ISO image that can be used as install medium and more importantly to update an existing installation.

What do we want to achieve?

  • Clone and commit the upstream build tools used to generate the image
  • Store the final generated ISO image as artifact in Gitlab
  • Have a version number that identifies the release branch, the specific commit message via git hash and the date
  • Have author information with name and email of the person that generated the ISO image.
  • Have an audit log that allows to trace back how the ISO image was generated (and in the future what went into it)
  • Have everything internal so that it is robust against external tampering and mistakes

The following screenshot shows the running vyos-build docker image creation and the iso generation job.

VyOS Gitlab CI/CD Pipeline

Please note that for audit reasons and to prevent future supply chain attacks the internal commit message includes the 10 last commit messages of the upstream vyos/vyos-build repository and the content of the upstream vyos-build repository used to generate the VyOS ISO image.

The content of the internal repository, including the upstream vyos-build directory is shown in the screenshot below.

VyOS Image Gitlab Repository content

The important jobs in the Gitlab CI/CD pipeline are outlined below. The code snippet is taken from the .gitlab-ci.yml file in the root directory of the repository.

stages:
  - build
  - iso

create vyos builder:
  stage: build
  image:
    name: gcr.io/kaniko-project/executor:debug
    entrypoint: ['']
  tags:
    - privileged
  script:
    - cat ${INTERNAL_ROOT_CA_FILE} >> /kaniko/ssl/certs/additional-ca-cert-bundle.crt
    - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" \
        > /kaniko/.docker/config.json
    - /kaniko/executor --context $CI_PROJECT_DIR/vyos-build/docker \
        --dockerfile $CI_PROJECT_DIR/vyos-build/docker/Dockerfile \
        --destination $CI_REGISTRY_IMAGE/builder:${CI_COMMIT_REF_NAME}
  only:
    - master
    - "1.3"

create vyos iso:
  stage: iso
  image:
    name: registry.local.xy/infrastructure/vyos-image/builder:${CI_COMMIT_REF_NAME}
    entrypoint: [""]
  tags:
    - privileged
  before_script:
    - VERSION=$(<./.version)
    - AUTHOR="${GITLAB_USER_NAME} <${GITLAB_USER_EMAIL}>"
    - cd ./vyos-build/
  script:
    - ./configure --architecture amd64 --build-by "${AUTHOR}" --build-type release --version "${VERSION}" --custom-package vim
    - cat build/build-config.json
    - sudo make iso
  artifacts:
    paths:
      - ./vyos-build/build/live-image-amd64.hybrid.iso
    expire_in: 1 month
  only:
    - master
    - "1.3"

We create a iso image from the 1.3 (upcoming/current stable version) and the master (rolling release) branch. The mapping between inernal feature branches and upsream versions is outlined in the ./.env file below.

declare -A versions
versions[1.3]="1.3"
versions[1.4]="1.4"
versions[master]="1.4"

declare -A branches
branches[1.3]="equuleus"
branches[1.4]="current"
branches[master]="current"

VERSION=${versions[$(git branch --show-current)]}
BRANCH=${branches[$(git branch --show-current)]}
Author

Alex Oberhauser

Alex Oberhauser is a tech-entrepreneur, innovator and former C-level executive. He is currently working on user controlled identities and the empowerment of the end-users, with privacy and security as part of the value proposition, not as an afterthought.