
Nginx Inc. provides access to the nginx-plus package and repository using SSL certificates. Their instructions include the configuration of apt for Ubuntu, but for people using apt-mirror and Puppet to manage their internal servers, additional custom configurations are required.
The standard apt configuration for nginx-plus might look like this:
1 2 3 4 5 6 7 8 |
$ cat /etc/apt/apt.conf.d/90nginx Acquire::https::plus-pkgs.nginx.com::Verify-Peer "true"; Acquire::https::plus-pkgs.nginx.com::Verify-Host "true"; Acquire::https::plus-pkgs.nginx.com::CaInfo "/etc/ssl/nginx/CA.crt"; Acquire::https::plus-pkgs.nginx.com::SslCert "/etc/ssl/nginx/nginx-repo.crt"; Acquire::https::plus-pkgs.nginx.com::SslKey "/etc/ssl/nginx/nginx-repo.key"; |
The connection to the nginx-plus repository must be made using HTTPS and authentication is handled by client certificates. As provided, apt-mirror is not able to manage SSL certificates, so two sections in the apt-mirror script must be modified. The %config_variables
array defines the settings read from its configuration files. We will add the ‘certificate’, ‘private_key’, and ‘ca_certificate’ settings to the array.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
my %config_variables = ( "defaultarch" => `dpkg --print-installation-architecture 2>/dev/null` || 'i386', "nthreads" => 20, "base_path" => '/var/spool/apt-mirror', "mirror_path" => '$base_path/mirror', "skel_path" => '$base_path/skel', "var_path" => '$base_path/var', "cleanscript" => '$var_path/clean.sh', "_contents" => 1, "_autoclean" => 0, "_tilde" => 0, "limit_rate" => '100m', "run_postmirror" => 1, "postmirror_script" => '$var_path/postmirror.sh', "certificate" => '', "private_key" => '', "ca_certificate" => '' ); |
If these configuration settings are found, we must pass them to wget.
1 2 3 4 5 6 7 8 9 10 11 |
if($pid == 0) { my $ca = get_variable("ca_certificate") ? '--ca-certificate='.get_variable("ca_certificate") : ''; my $cert = get_variable("certificate") ? '--certificate='.get_variable("certificate") : ''; my $key = get_variable("private_key") ? '--private-key='.get_variable("private_key") : ''; exec '/usr/bin/wget', $ca, $cert, $key, '--no-cache', '--limit-rate='.get_variable("limit_rate"), '-t', '5', '-r', '-N', '-l', 'inf', '-o', get_variable("var_path")."/$stage-log.$i", '-i', get_variable("var_path")."/$stage-urls.$i"; die("\n\nCould not run wget, please make sure its installed and in your path\n\n"); } |
Here is an example template for Puppet to create the apt-mirror configuration files, including the optional SSL certificate paths.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
$ cat /etc/puppet/modules/apt/templates/mirror.list.erb # ____ _ _____ _ _ # | _ \ _ _ _ __ _ __ ___| |_ | ___(_) | ___ # | |_) | | | | '_ \| '_ \ / _ \ __| | |_ | | |/ _ \ # | __/| |_| | |_) | |_) | __/ |_ | _| | | | __/ # |_| \__,_| .__/| .__/ \___|\__| |_| |_|_|\___| # |_| |_| <% if @subdir -%>set base_path /var/spool/apt-mirror/<%= @subdir %> <% else -%>set base_path /var/spool/apt-mirror <% end -%> set mirror_path $base_path/mirror set skel_path $base_path/skel set var_path $base_path/var set cleanscript $var_path/clean.sh set defaultarch amd64 set postmirror_script $var_path/postmirror.sh set run_postmirror 0 set nthreads 10 set _tilde 0 <% if @ca_certificate -%>set ca_certificate <%= @ca_certificate %> <% end -%> <% if @certificate -%>set certificate <%= @certificate %> <% end -%> <% if @private_key -%>set private_key <%= @private_key %> <% end -%> <% @dist.each do |d| %> deb <%= @uri %> <%= d %> <%= @components %> <% if @source == true -%>deb-src <%= @uri %> <%= d %> <%= @components %><% end -%> <% end %> |
And here is an example Puppet module, with an apt::mirror class and apt::mirror::repository definition, to generate the configuration files from that template. This module also includes a scheduling feature to automate mirror updates, though this feature may not be useful for most production environments (where more stringent processes may be required for controlled mirror updates).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
$ cat /etc/puppet/modules/apt/manifests/mirror.pp class apt::mirror { file { "/etc/apt/mirror.list.d": ensure => directory, owner => "root", group => "root", mode => "0755", recurse => true, purge => true, } } define apt::mirror::repository ( $subdir = "", # required for the template $uri = "", $dist = "", $components = "", $ca_certificate = false, $certificate = false, $private_key = false, $source = false, $ensure = present, $sched = "", ) { file { "/etc/apt/mirror.list.d/${name}.list": ensure => $ensure, owner => "root", group => "root", mode => "0444", content => template("apt/mirror.list.erb"); } # only run the apt-mirror command when the apt-mirror config file is first created exec { "apt-mirror-${name}": command => "/usr/bin/apt-mirror /etc/apt/mirror.list.d/${name}.list && touch /root/.apt-mirror-${name}", timeout => 3600, returns => [ 0 ], require => File[ "/usr/bin/apt-mirror", "/etc/apt/mirror.list.d/${name}.list" ], creates => "/root/.apt-mirror-${name}", unless => "/usr/bin/test -f /root/.apt-mirror-${name}"; } # optionally create cronjobs to automate the apt-mirror updates case $sched { /^(daily|hourly|monthly|weekly)$/: { file { "/etc/cron.${sched}/apt-mirror-${name}": ensure => $ensure, owner => "root", group => "root", mode => "0744", content => "[ -f /etc/apt/mirror.list.d/${name}.list ] && /usr/bin/apt-mirror /etc/apt/mirror.list.d/${name}.list\n", } } default: { file { "/etc/cron.daily/apt-mirror-${name}": ensure => absent } file { "/etc/cron.hourly/apt-mirror-${name}": ensure => absent } file { "/etc/cron.monthly/apt-mirror-${name}": ensure => absent } file { "/etc/cron.weekly/apt-mirror-${name}": ensure => absent } } } } |
A practical example, using the apt-mirror Puppet module above, may look like this (assuming your Puppet configurations use ‘role’ and ‘application’ based classes).
The ‘deploy’ role includes the role::deploy::apt::mirror class, which then includes the apt::mirror module class, and calls the apps::apt::mirror::nginx::plus definition for all three supported environments — production, staging, and development (each environment has its own mirror, which can be updated and tested independently).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
$ cat /etc/puppet/manifests/role/deploy.pp class role::deploy { include role::deploy::apt::mirror } class role::deploy::apt::mirror { include apt::mirror apps::apt::mirror::nginx::plus { [ "prd", "stg", "dev" ]: } # # ... rinse and repeat for all mirror definitions ... # } |
The apps::apt::mirror::nginx::plus definition is located within an apt-mirror ‘application’ manifest. It executes the apt::mirror::repository module definition for each of the environment names we provide.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
$ cat /etc/puppet/manifests/apps/apt-mirror.pp define apps::apt::mirror::nginx::plus { $uri = "https://plus-pkgs.nginx.com/ubuntu" $dist = [ "precise", "raring", ] $components = "nginx-plus" apt::mirror::repository { "${name}-nginx-plus": subdir => $name, uri => $uri, dist => $dist, components => $components, ca_certificate => "/etc/ssl/nginx/CA.crt", certificate => "/etc/ssl/nginx/nginx-repo.crt", private_key => "/etc/ssl/nginx/nginx-repo.key", } } |
The resulting apt-mirror configuration files may look like this.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
$ ls -al /etc/apt/mirror.list.d/*-nginx-plus.list -r--r--r-- 1 root root 898 Feb 5 15:18 /etc/apt/mirror.list.d/dev-nginx-plus.list -r--r--r-- 1 root root 898 Feb 5 15:18 /etc/apt/mirror.list.d/prd-nginx-plus.list -r--r--r-- 1 root root 898 Feb 5 15:18 /etc/apt/mirror.list.d/stg-nginx-plus.list root@deploy:~$ cat /etc/apt/mirror.list.d/dev-nginx-plus.list # ____ _ _____ _ _ # | _ \ _ _ _ __ _ __ ___| |_ | ___(_) | ___ # | |_) | | | | '_ \| '_ \ / _ \ __| | |_ | | |/ _ \ # | __/| |_| | |_) | |_) | __/ |_ | _| | | | __/ # |_| \__,_| .__/| .__/ \___|\__| |_| |_|_|\___| # |_| |_| set base_path /var/spool/apt-mirror/dev set mirror_path $base_path/mirror set skel_path $base_path/skel set var_path $base_path/var set cleanscript $var_path/clean.sh set defaultarch amd64 set postmirror_script $var_path/postmirror.sh set run_postmirror 0 set nthreads 10 set _tilde 0 set ca_certificate /etc/ssl/nginx/CA.crt set certificate /etc/ssl/nginx/nginx-repo.crt set private_key /etc/ssl/nginx/nginx-repo.key deb https://plus-pkgs.nginx.com/ubuntu precise nginx-plus deb https://plus-pkgs.nginx.com/ubuntu raring nginx-plus |