{"id":278,"date":"2017-11-15T10:46:26","date_gmt":"2017-11-15T08:46:26","guid":{"rendered":"https:\/\/www.tobanet.de\/s\/?p=278"},"modified":"2020-12-19T12:02:26","modified_gmt":"2020-12-19T10:02:26","slug":"create-your-own-debian-mirror-with-debmirror","status":"publish","type":"post","link":"https:\/\/www.tobanet.de\/s\/2017\/11\/create-your-own-debian-mirror-with-debmirror\/","title":{"rendered":"Create your own Debian mirror with debmirror"},"content":{"rendered":"\n<p><strong>We will walk through these steps to get the local Debian mirror up and running:<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>make sure you have enough space on your harddrive<\/li><li>install <code>debmirror<\/code>, configure a cronjob to sync data<\/li><li>make your mirror available to your clients (via apache or nfs)<\/li><li>keep an eye on your cronjob &#8211; from time to time your script may have trouble to sync<\/li><li>configure <code>sources.list<\/code> to use your local mirror<\/li><\/ol>\n\n\n\n<!--more-->\n\n\n\n<h2 class=\"wp-block-heading\" id=\"space_requirements\">1. Space requirements<\/h2>\n\n\n\n<p>You will need some space to host the mirror.<\/p>\n\n\n\n<p>My local mirror hosts the distributions for jessie and stretch with architecture amd64.<\/p>\n\n\n\n<p>This setup currently (2017-11) consumes ~113 GB.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"installation\">2. Installation<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"the_basics\">The basics<\/h3>\n\n\n\n<p>My debmirror runs on <strong>jessie<\/strong>. But that&#8217;s not really relevant here.<\/p>\n\n\n\n<p>First, install the debmirror and debian-keyring package:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">apt-get install debmirror debian-keyring<\/pre>\n\n\n\n<p>Decide where to store your mirror:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">mkdir \/srv\/mirror<\/pre>\n\n\n\n<p>Add a user who will run the mirror script:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">groupadd mirror\nuseradd -d \/srv\/mirror -c \"Debmirror\" -g mirror mirror<\/pre>\n\n\n\n<p>Change permissions:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">chown -R mirror.mirror \/srv\/mirror<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"handle_gpg_keys\">Handle gpg keys<\/h3>\n\n\n\n<p>gpg uses <code>trustdb.gpg<\/code> as the default keyring; debmirror however expects the keys to reside in <code>trustedkeys.gpg<\/code> !<\/p>\n\n\n\n<p>If something breaks that&#8217;s usually because some keys have been added to the official keyring and are missing locally.<\/p>\n\n\n\n<p><strong>Import gpg keys.<\/strong><br>The easiest thing is to import the official debian-archive-keyring for debmirror.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"false\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># become mirror\nsu - mirror\n \n# 1st import the following:\ngpg --no-default-keyring --keyring trustedkeys.gpg --import \/usr\/share\/keyrings\/debian-archive-keyring.gpg\n \n# check the key list, it should give you something like this:\ngpg --list-keys --keyring trustedkeys.gpg\n \n\/srv\/mirror\/.gnupg\/trustedkeys.gpg\n----------------------------------\n \npub   4096R\/473041FA 2010-08-27 [verf\u00e4llt: 2018-03-05]\nuid                  Debian Archive Automatic Signing Key (6.0\/squeeze) &lt;ftpmaster@debian.org>\n \npub   4096R\/B98321F9 2010-08-07 [verfallen: 2017-08-05]\nuid                  Squeeze Stable Release Key &lt;debian-release@lists.debian.org>\n \npub   4096R\/65FFB764 2012-05-08 [verf\u00e4llt: 2019-05-07]\nuid                  Wheezy Stable Release Key &lt;debian-release@lists.debian.org>\n \npub   4096R\/46925553 2012-04-27 [verf\u00e4llt: 2020-04-25]\nuid                  Debian Archive Automatic Signing Key (7.0\/wheezy) &lt;ftpmaster@debian.org>\n \npub   4096R\/2B90D010 2014-11-21 [verf\u00e4llt: 2022-11-19]\nuid                  Debian Archive Automatic Signing Key (8\/jessie) &lt;ftpmaster@debian.org>\n \npub   4096R\/518E17E1 2013-08-17 [verf\u00e4llt: 2021-08-15]\nuid                  Jessie Stable Release Key &lt;debian-release@lists.debian.org>\n \npub   4096R\/C857C906 2014-11-21 [verf\u00e4llt: 2022-11-19]\nuid                  Debian Security Archive Automatic Signing Key (8\/jessie) &lt;ftpmaster@debian.org>\n \npub   4096R\/1A7B6500 2017-05-20 [verf\u00e4llt: 2025-05-18]\nuid                  Debian Stable Release Key (9\/stretch) &lt;debian-release@lists.debian.org>\n \npub   4096R\/F66AEC98 2017-05-22 [verf\u00e4llt: 2025-05-20]\nuid                  Debian Archive Automatic Signing Key (9\/stretch) &lt;ftpmaster@debian.org>\nsub   4096R\/B7D453EC 2017-05-22 [verf\u00e4llt: 2025-05-20]\n \npub   4096R\/8AE22BA9 2017-05-22 [verf\u00e4llt: 2025-05-20]\nuid                  Debian Security Archive Automatic Signing Key (9\/stretch) &lt;ftpmaster@debian.org>\nsub   4096R\/331F7F50 2017-05-22 [verf\u00e4llt: 2025-05-20]<\/pre>\n\n\n\n<p><em>From time to time keys will be updated or removed. We just need to sync keys from debian-archive-keyring. gpg will automatically skip duplicates and add what is missing. This step is vitally important when you add a new distribution like stretch.<\/em><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># update the keyring, same procedure as install:\ngpg --no-default-keyring --keyring trustedkeys.gpg --import \/usr\/share\/keyrings\/debian-archive-keyring.gpg \n&nbsp;\n# and verify what's in the keyring:\ngpg --list-keys --keyring trustedkeys.gpg<\/pre>\n\n\n\n<p><strong>NOTE:<\/strong><\/p>\n\n\n\n<p>If you do not have ~\/.gnupg\/trustedkeys.gpg then you can also copy the complete archive keyring file (as user &#8216;mirror&#8217;):<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">cp \/usr\/share\/keyrings\/debian-archive-keyring.gpg ~\/.gnupg\/trustedkeys.gpg <\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"script_cronjob\">Script &amp; Cronjob<\/h3>\n\n\n\n<p><strong>Create a script to be run by cron as root.<\/strong><br>The script below will mirror jessie and stretch.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">#!\/bin\/bash\n&nbsp;\n# sourcehost: choose a mirror in your proximity!\nHOST=ftp2.de.debian.org;\n&nbsp;\n# destination directory\nDEST=\/srv\/mirror\/debian\n&nbsp;\n# Debian version(s) to mirror\nDIST=jessie,stretch\n&nbsp;\n# architecture\nARCH=amd64\n&nbsp;\n# log timestamp\nlogger -t mirror[$$] updating Debian mirror\n&nbsp;\nsu mirror -c \\\n \"debmirror ${DEST} \\\n --nosource \\\n --host=${HOST} \\\n --root=\/debian \\\n --dist=${DIST} \\\n --section=main,contrib,non-free,main\/debian-installer \\\n --i18n \\\n --arch=${ARCH} \\\n --passive --cleanup \\\n $VERBOSE\"\n&nbsp;\nlogger -t mirror[$$] finished updating Debian mirror<\/pre>\n\n\n\n<p>Edit \/etc\/cron.d\/local-debmirror:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># debmirror\n38 04 * * 1-5 root \/root\/scripts\/mirror<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"make_the_mirror_available\">3. Make the mirror available<\/h2>\n\n\n\n<p>The easiest way would be to set up a webserver (e.g. apache) to serve the data to your clients.<\/p>\n\n\n\n<p>Your mirror directory tree should look like:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">tree -d -L 2 \/srv\/mirror\/debian\n\/srv\/mirror\/debian\n\u251c\u2500\u2500 dists\n\u2502&nbsp;&nbsp; \u251c\u2500\u2500 jessie\n\u2502&nbsp;&nbsp; \u251c\u2500\u2500 oldstable -&gt; jessie\n\u2502&nbsp;&nbsp; \u251c\u2500\u2500 stable -&gt; stretch\n\u2502&nbsp;&nbsp; \u2514\u2500\u2500 stretch\n\u251c\u2500\u2500 pool\n\u2502&nbsp;&nbsp; \u251c\u2500\u2500 contrib\n\u2502&nbsp;&nbsp; \u251c\u2500\u2500 main\n\u2502&nbsp;&nbsp; \u2514\u2500\u2500 non-free\n\u2514\u2500\u2500 project\n    \u2514\u2500\u2500 trace<\/pre>\n\n\n\n<p>Decide how you want to access the mirror &#8211; debmirror.example.com sounds great, doesn&#8217;t it? Don&#8217;t forget to update your DNS!<\/p>\n\n\n\n<p>Create a virtual host configuration like so: <a href=\"file:\/\/\/C:\/Users\/Thorsten\/Downloads\/Tobanet%20Dokuwiki\/www.tobanet.de\/dokuwiki\/_export\/code\/debmirrorfbb6?codeblock=10\">\/etc\/apache2\/sites-available\/debmirror<\/a><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">&lt;VirtualHost *:80&gt;\n        ServerName debmirror.example.com\n        ServerAdmin webmaster@localhost\n\n        DocumentRoot \/srv\/mirror\n        &lt;Directory \/&gt;\n                Options FollowSymLinks\n                AllowOverride None\n        &lt;\/Directory&gt;\n        &lt;Directory \/srv\/mirror&gt;\n                Options Indexes FollowSymLinks MultiViews\n                AllowOverride All\n                Order allow,deny\n                allow from all\n        &lt;\/Directory&gt;\n\n        ErrorLog \/var\/log\/apache2\/debmirror.example.com-error.log\n\n        # Possible values include: debug, info, notice, warn, error, crit,\n        # alert, emerg.\n        LogLevel warn\n\n        CustomLog \/var\/log\/apache2\/debmirror.example.com-access.log combined\n        ServerSignature On\n\n&lt;\/VirtualHost&gt;<\/pre>\n\n\n\n<p>To tune your landing page on debmirror.example.com, you can pimp your <a href=\"file:\/\/\/C:\/Users\/Thorsten\/Downloads\/Tobanet%20Dokuwiki\/www.tobanet.de\/dokuwiki\/apache_directory_index.html\">directory index<\/a>.<\/p>\n\n\n\n<p>And finally enable the shiny new site:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">a2ensite debmirror\n\/etc\/init.d\/apache force-reload<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"cronjob_monitoring\">4. Cronjob monitoring<\/h2>\n\n\n\n<p>The least you can do is to make sure you recieve any output your cronjob generates by mail.<\/p>\n\n\n\n<p>So check whether your <code>\/etc\/aliases<\/code> is setup properly to redirect any mail to your <code>mirror<\/code> user to your preferred mailaccount: <a href=\"file:\/\/\/C:\/Users\/Thorsten\/Downloads\/Tobanet%20Dokuwiki\/www.tobanet.de\/dokuwiki\/_export\/code\/aliases48e9?codeblock=12\">aliases<\/a><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># \/etc\/aliases\nroot: localuser, you@example.com\n[...]\nmirror: you@example.com\n[...]<\/pre>\n\n\n\n<p>Run <code>newaliases<\/code> and verify you receive mail sent to the mirror user. If you are not directly connected to the internet and sitting behind a NAT router, you will have to tune your mailserver configuration.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"configure_your_clients\">5. Configure your clients<\/h2>\n\n\n\n<p>Now we are done on the server side. It is time to actually use the local mirror. All we have to do is to enable the mirror in <code>\/etc\/apt\/sources.list<\/code> &#8211; just replace the existing upstream resource with something like that: <a href=\"file:\/\/\/C:\/Users\/Thorsten\/Downloads\/Tobanet%20Dokuwiki\/www.tobanet.de\/dokuwiki\/_export\/code\/sources1a44.list?codeblock=13\">sources.list<\/a><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">[...]\n\n# Jessie:\ndeb http:\/\/debmirror.example.com\/debian\/ jessie main contrib non-free\n\n[...]<\/pre>\n\n\n\n<p>Now you can happily <code>apt-get update<\/code> and with your next <code>apt-get install whatever<\/code> the selected package(s) will be retrieved from your local mirror.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>We will walk through these steps to get the local Debian mirror up and running: make sure you have enough space on your harddrive install debmirror, configure a cronjob to sync data make your mirror available to your clients (via apache or nfs) keep an eye on your cronjob &#8211; from time to time your script may have trouble to sync configure sources.list to use your local mirror<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11],"tags":[29],"class_list":["post-278","post","type-post","status-publish","format-standard","hentry","category-linux","tag-debian"],"_links":{"self":[{"href":"https:\/\/www.tobanet.de\/s\/wp-json\/wp\/v2\/posts\/278","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.tobanet.de\/s\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tobanet.de\/s\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tobanet.de\/s\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tobanet.de\/s\/wp-json\/wp\/v2\/comments?post=278"}],"version-history":[{"count":3,"href":"https:\/\/www.tobanet.de\/s\/wp-json\/wp\/v2\/posts\/278\/revisions"}],"predecessor-version":[{"id":288,"href":"https:\/\/www.tobanet.de\/s\/wp-json\/wp\/v2\/posts\/278\/revisions\/288"}],"wp:attachment":[{"href":"https:\/\/www.tobanet.de\/s\/wp-json\/wp\/v2\/media?parent=278"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tobanet.de\/s\/wp-json\/wp\/v2\/categories?post=278"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tobanet.de\/s\/wp-json\/wp\/v2\/tags?post=278"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}