Penguin

APT through a WebProxy

Using APT through a WebProxy is not documented very well, but is really easy. All you need is to add something like this to your /etc/apt/apt.conf
Acquire {
    Retries "0";
    Http {
        Proxy "http://user:pass@proxy:port/";
    }
};

Apparently APT will also honour the http_proxy EnvironmentVariable (or ftp_proxy for ftp URIs), which is used by some network-related applications.

Ratelimiting APT Downloads

See the relevant notes about limiting download speeds on the DebianNotes page

Reinstalling or fixing packages

use apt-get --reinstall install <package>

You may wish to just reconfigure the package in which case you can do dpkg-reconfigure <package>

Secure APT: Verifying Packages

Starting with version 0.6, which is now in Debian unstable (sid/etch) and Ubuntu, APT has the capability to verify package signatures. This is done by verifying that the Release file is signed by a trusted key. The signed release file then contains the MD5 checksums of the packages which you can verify against what you just downloaded. This protects against two attacks:

  • Mirror Network Compromise -- like if your favourite mirror gets hacked
  • Network Layer Attacks -- DNS Spoofing, Man in the Middle attacks, etc

To have APT automatically verify downloads you need to import a suitable key. For Debian:

    gpg --keyserver keyring.debian.org --recv 4F368D5D
    gpg --export 4F368D5D | apt-key add -

Note: if you just trusted that command and imported that key, you probably don't need apt-secure anyway... You can get Debian's key from http://www.debian.org/releases/, and there is a Debian administration article on the subject.

For Ubuntu, you can do the following:

apt-key add /usr/share/keyrings/ubuntu-archive-keyring.gpg

After you've got the key, run apt-get update once and you should be away.

See

Pinning Packages

If you want to run Stable, but want to have the ability to install packages or source from Testing or Unstable when there is no Stable equivalent, you can pin the releases to certain priorities. Normally, the highest version of an available package wins, but we will override that.

Create an /etc/apt/preferences file. A simple example may look like this
Package: *
Pin: release o=volatile.debian.net,a=sarge
Pin-Priority: 990

Package: *
Pin: release o=volatile.debian.net,a=sarge-sloppy
Pin-Priority: 990

Package: *
Pin: origin security.debian.org
Pin-Priority: 900

Package: *
Pin: release a=stable
Pin-Priority: 700

Package: *
Pin: release a=testing
Pin-Priority: 650

Package: *
Pin: release a=unstable
Pin-Priority: 600

Note the descending values. This example includes the volatile distribution as well. The priority is set higher than the security distribution, as we want to favour it over the (normally higher rating) security packages.

Since Stable has the highest pin-priority, it will be installed preferentially over Testing or Unstable. Uncomment stable and unstable in the AptSourcesList file at the same time. See Apt-Pinning for Beginners for more information.

You can then specifically request packages from the Testing or Unstable repository by using one of the following forms:

apt-get install package -t distrib
apt-get install package/distrib
apt-get install package=version

(If you see advice to set the APT::Default-Release preference in apt.conf(5), ignore it. See Using APT with more than 2 sources for details.)

If you're worried about which version of packages apt will prefer, try apt-cache policy <package>. If you're interested in developing your own /etc/apt/preferences file for pinning, look at the output of apt-cache policy with no package name for fields you can use.

Private APT repository pico-HowTo

SysAdmins responsible for more than a few servers will often need to roll out customized Packages or security patches to many systems. A custom APT source makes the job much easier.

All you really need is the apt-ftparchive(1) utility. First, put all the Debs in a directory reachable via a WebServer. Say the directory is /usr/local/httpd/packages and is reachable over HTTP as http://example.com/packages/. Then change directory to /usr/local/httpd/packages and run

apt-ftparchive packages . > Packages

That's it. Now add

deb  http://example.com/packages  ./

to the AptSourcesLists on your machines and run apt-get update on them and you'll be able to apt-get install foo to install your custom package foo.

Make sure to build your packages with proper version incrememts. The following shell script makes good suggestions
#!/bin/sh
VERSTR='+0.local.'
case $1 in
    *${VERSTR}[0-9]*)
      REV=${1##*${VERSTR}}
      echo ${1%${VERSTR}*}${VERSTR}$((++REV));;
    *-*)
      echo ${1}${VERSTR}1;;
    *)
      echo ${1}-0${VERSTR}1;;
esac
Save it as bump-version and call it with the current version number to get a suggestion for the next version number to use
$ bump-version 1.0
1.0-0+0.local.1
$ bump-version 1.0-1
1.0-1+0.local.1

Or alternatively, use pinning.

Taken from Re: custom sec updates.

For a slightly more comprehensive guide to building a custom repository see http://familiasanchez.net/sanchezr/?page=debrepository

Downloading packages for an unconnected machine

You can ask apt-get to compute the list of dependencies for you and give you a list of Packages and their download URLs, rather than actually attempting an action, by giving it the --print-uris switch. Do this on the machine with no (or limited) net connection
apt-get --print-uris upgrade | awk '{ print "wget -O", $2, $1 }' > /tmp/wget-script

Instead of the upgrade action, you can also use install foo or something else. The result will be a file of the form

wget -O e2fslibs_1.38-1_i386.deb 'http://ftp.nz.debian.org/debian/pool/main/e/e2fsprogs/e2fslibs_1.38-1_i386.deb'
wget -O e2fsprogs_1.38-1_i386.deb 'http://ftp.nz.debian.org/debian/pool/main/e/e2fsprogs/e2fsprogs_1.38-1_i386.deb'
wget -O findutils_4.2.22-2_i386.deb 'http://ftp.nz.debian.org/debian/pool/main/f/findutils/findutils_4.2.22-2_i386.deb'
wget -O grep_2.5.1.ds1-5_i386.deb 'http://ftp.nz.debian.org/debian/pool/main/g/grep/grep_2.5.1.ds1-5_i386.deb'

This is a ready-made Shell script you can copy to a FloppyDisk, KeyDrive or the like. Take it to a machine with an internet connection and execute it to download the Debs to the current directory. Then transport these files back to the unconnected machine.

Once you have mounted the media on the unconnected machine, you can install the Packages either:

  • directly from their location on the media by using apt-get -o dir::cache::archives=/mnt/usb/ action
  • or by copying the files to /var/cache/apt/archives/ and using apt-get -u action or one of the other APT tools, such as aptitude(1) or synaptic(1)?.

Downgrading a package

In theory you can do:

aptitude install package_name=version_num

but this doesn't always work. Instead download the .deb file manually from your mirror (look in debian/pool) and then type the following

dpkg --install package_name_version_num.deb

where package_name and version_num are replaced by the package name you are working with and the version number.

Having multiple machines update over a slow line

You can use apt-proxy(8)? on one machine and point all your machines to use the proxy. apt-proxy will download a package the first time a machine asks for it, then caches the package locally for the rest of the machines on the network to use.

One thing to be aware of with apt-proxy(8)? is that reasonably often it will appear to be getting no throughput at all. What is actually happening is that apt-proxy(8)? is downloading the file in the background and will start sending to you when it has finished downloading the entire file.

Releasing disk space

APT keeps copies of all the Packages you downloaded in /var/cache/apt/archive, which adds up over time. To remove all but the most recent copies, issue aptitude autoclean

Holding packages

If you need to pin a certain package, you can easily do this with aptitude:

root@box:~ # aptitude hold linux-image-2.6.15-26-server
  <snip>
root@box:~ # aptitude dist-upgrade
Reading package lists... Done
Building dependency tree... Done
Reading extended state information
Initializing package states... Done
Building tag database... Done
The following packages have been kept back:
  linux-image-2.6.15-26-server
The following packages will be upgraded:
  bind9 bind9-host clamav clamav-base clamav-daemon clamav-freshclam
  <snip>

There is no command-line method for doing this with apt-get. I wanted to do this as I was installing a -27 kernel as well, and upon a successful reboot, I'd just remove the (outdated) -26 package. It is for this reason, and others that Debian have recommended using aptitude instead of apt. IanMcDonald strongly recommends using command line only for aptitude - the text GUI is awful and will probably trash your system (it did his once!). If you want a GUI tool use one provided with your distro such as Synaptic or with Ubuntu just use Add/remove programs in many cases.

Forcing accepting specific configuration files

You can cause apt-get/dpkg to automatically answer 'yes' or 'no' to installing the newer version of a configuration file (conffile).

  • To force accepting the new conffile: -o Dpkg::Options::="--force-confnew"
  • To force accepting the old conffile: -o Dpkg::Options::="--force-confold"

You need the :: after the Options.

If your configuration files are managed with UCF, you set environment variables rather than using command line parameters:

  • To force accepting the new conffile: UCF_FORCE_CONFFNEW=yes
  • To force accepting the old conffile: UCF_FORCE_CONFFOLD=yes

Note the extra f.

Working out why apt has made a package choice

Sometimes apt may decide to install or uninstall a package and you have no idea why it made this choice. To see its reasoning, add

-o Debug::pkgProblemResolver=yes

to the command