Commit 3f1a351d authored by Tails developers's avatar Tails developers

Install TBB in a custom way instead of installing Iceweasel.

Instead of installing the iceweasel package (and friends) we now fetch
the TBB tarballs at build-time and extract the Tor Browser, browser
add-ons and langpacks, and browser user data into sensible places. We
try to keep something like the old organization as much as possible.

Unfortunately this drops language support to whatever subset that the
TBB supports.
parent 786eceac
......@@ -210,6 +210,11 @@ Package: xul-ext-noscript
Pin: release o=Debian Backports,n=wheezy-backports
Pin-Priority: 999
Explanation: Block installation of iceweasel until it has been removed from our APT repo
Package: iceweasel
Pin: origin
Pin-Priority: -1
Explanation: weirdness in chroot_apt install-binary
Package: *
Pin: release o=chroot_local-packages
......@@ -219,10 +224,6 @@ Package: *
Pin: origin
Pin-Priority: 1005
Package: *
Pin: origin
Pin-Priority: 990
Package: *
Pin: release o=Debian,n=wheezy-updates
Pin-Priority: 990
set -eu
echo "Install the Tor Browser"
# Get the below with `grep "tor-browser-linux32-linux32-.*\.tar.xz" sha256sums.txt`
BUNDLES="$(cat <<EOF
6d45a3592f14c5d9db76d8567722cf21339ee87bb6a24e79899e8f1b1a65fb09 tor-browser-linux32-3.6.5_ar.tar.xz
57cb7ec7031ccdd6f045b075e51653078aa5040065dde75398eb2d57ef1bd035 tor-browser-linux32-3.6.5_de.tar.xz
ce9ee66dbde246acac9e2574317fc983b7ed1086591d60e7124a446d6dd1fea5 tor-browser-linux32-3.6.5_en-US.tar.xz
9953c8ccd95981e83ff6f22ed6cdfa54a114323d43d78a8a2ab1aa7a4d727cf6 tor-browser-linux32-3.6.5_es-ES.tar.xz
e2bf78eaaec3ca4e9e1bc52db6077676c2bd6e0a624283ec37cc70aad9c65730 tor-browser-linux32-3.6.5_fa.tar.xz
30f2dc943fb1ff0aaaf3ea7d7f1c869b5a85127f594322c1ec637fa43c8a5ceb tor-browser-linux32-3.6.5_fr.tar.xz
d28adc1385b412ef06deb8d1f46cf123f7f582b3d0c057effc342bbbba613a29 tor-browser-linux32-3.6.5_it.tar.xz
689d387bdaf21d2b92ba59b298e863ca0be011e63538e4948b4f445c7461fa4e tor-browser-linux32-3.6.5_ko.tar.xz
dc940b23531616f11cc1a8d36a077ccd6d0bd1cf16ade8a1688d791f5465b1ce tor-browser-linux32-3.6.5_nl.tar.xz
f5a9ad3801d9102a4a32e7abd3f35c341d4a98e80bd83149aa1023c86f1c3fc4 tor-browser-linux32-3.6.5_pl.tar.xz
1a56594213ece5fb28f4f7d7ed02b9d87fd2ab0699fae4f11aa9c307a711afcd tor-browser-linux32-3.6.5_pt-PT.tar.xz
8c86bd7c40f95d50ce572aa61301001d76882e8f024507b82e0797121e3a00cd tor-browser-linux32-3.6.5_ru.tar.xz
e4fad4cb87950dce71e663541cb2ba412eac3ced74f74b5e6317381ab67b6a09 tor-browser-linux32-3.6.5_tr.tar.xz
6f2e40b14f81fbd44f78a9c6c2aa7bda3164b679497ff1043bb4e0e4a4eeb087 tor-browser-linux32-3.6.5_vi.tar.xz
26a258feceebef43c789425fd0810141400504e117ea8229c36fbce76921b14c tor-browser-linux32-3.6.5_zh-CN.tar.xz
MAIN_BUNDLE="$(echo "${BUNDLES}" | grep -o "tor-browser-linux32-.*_en-US.tar.xz")"
VERSION="$(echo "${MAIN_BUNDLE}" | sed 's/tor-browser-linux32-\(.*\)_en-US.tar.xz/\1/')"
# Note that we cannot use https here since apt-cacher-ng (used by vagrant)
# gets confused and throws a 403. It doesn't matter, though, since we verify
# the checksums of each file downloaded.
# Later we're gonna split TBB's actual browser (binaries etc), user
# data and extension into these folders, respectively
mkdir -p "${TBB_INSTALL}" "${TBB_PROFILE}" "${TBB_EXT}"
# Use the builder's caching APT proxy, if any
if [ -e /etc/apt/apt.conf.d/00http-proxy ]; then
APT_PROXY=$(sed -n 's/Acquire::http::Proxy "\(.*\)";/\1/p' /etc/apt/apt.conf.d/00http-proxy)
export http_proxy="${APT_PROXY}"
export https_proxy="${APT_PROXY}"
TMP="$(mktemp -d)"
echo "${BUNDLES}" | while read expected_sha256 tarball; do
cd "${TMP}"
echo "Fetching ${TBB_DIST_URL}/${tarball} ..."
curl -O "${TBB_DIST_URL}/${tarball}"
actual_sha256="$(sha256sum "${TMP}/${tarball}" | cut -d' ' -f1)"
if [ "${actual_sha256}" != "${expected_sha256}" ]; then
echo "SHA256 mismatch for ${tarball}" >&2
exit 1
# We'll use the en-US bundle as our basis ...
tar -xJf "${TMP}/${MAIN_BUNDLE}" -C "${TMP}"
# ... only extracting the localization addon from the other ones, which
# we'll put in a global extensions directory that we'll symlink to so
# we don't have to deal with wasteful copies.
for tarball in "${TMP}"/tor-browser-*.tar.xz; do
locale="$(echo "${tarball}" | sed "s@^.*/tor-browser-.*_\(.*\)\.tar\.xz@\1@")"
if [ "${locale}" = en-US ]; then
cd "${TMP}"
tar xJf "${tarball}" "${xpi}"
mv "${xpi}" "${TBB_EXT}"
# We don't want tor-launcher to be part of the browser, and we need our
# patched stand-alone version any way.
rm "${TBB_PREP}/Data/Browser/profile.default/extensions/"
# Remove TBB's torbutton since the "Tor test" will fail and about:tor
# will report an error. We'll install our own Torbutton later, which
# has the extensions.torbutton.test_enabled boolean pref as a workaround.
rm "${TBB_PREP}/Data/Browser/profile.default/extensions/"
# See comment below why we need the Browser sub-dir
mv "${TBB_PREP}/Browser" "${TBB_INSTALL}"/Browser
# The Tor Browser will fail, complaining about an incomplete profile,
# unless there's a readable Data/Browser/Caches in the parent
# directory of where the firefox executable is located.
mkdir -p "${TBB_INSTALL}"/Data/Browser/Caches
# Let's put all the bundled extensions in the global extensions directory
mv "${TBB_PREP}"/Data/Browser/profile.default/extensions/* "${TBB_EXT}"
rmdir "${TBB_PREP}"/Data/Browser/profile.default/extensions
# Create and install a fake iceweasel package so we can install our
# desired Debian-packaged Iceweasel addons
apt-get install --yes equivs
FAKE_ICEWEASEL_VERSION=$(sed -n 's/^Version=\(.*\)$/\1/p' "${TBB_INSTALL}"/Browser/application.ini)+fake1
cat > /root/iceweasel.control << EOF
Section: web
Priority: optional
Standards-Version: 3.6.2
Package: iceweasel
Maintainer: Tails developers <>
Architecture: all
Description: (Fake) Iceweasel
Make it possible to install Debian's Iceweasel addons without having to
install a real Iceweasel.
cd /root
equivs-build /root/iceweasel.control
dpkg -i iceweasel_"${FAKE_ICEWEASEL_VERSION}"_all.deb
rm /root/iceweasel*
apt-get install --yes xul-ext-adblock-plus xul-ext-foxyproxy-standard xul-ext-torbutton
ln -s /usr/share/xul-ext/adblock-plus/ "${TBB_EXT}"/'{d10d0bf8-f5b5-c8b4-a8b2-2b9879e08c5d}'
ln -s /usr/share/xul-ext/foxyproxy-standard/ "${TBB_EXT}"/foxyproxy@eric.h.jung
ln -s /usr/share/xul-ext/torbutton/ "${TBB_EXT}"/
cp -r "${TBB_PREP}"/Data/Browser/profile.default/* "${TBB_PROFILE}"/
mkdir -p "${TBB_PROFILE}"/extensions
for ext in "${TBB_EXT}"/*; do
ln -s "${ext}" "${TBB_PROFILE}"/extensions/
chown -R root:root "${TBB_INSTALL}" "${TBB_PROFILE}"
chmod -R a+rX "${TBB_INSTALL}" "${TBB_PROFILE}"
rm -rf "${TMP}"
set -e
# Remove unwanted iceweasel search plugins.
echo "Removing unwanted iceweasel search plugins"
rm "${PLUGIN_DIR}"/amazon*.xml
rm "${PLUGIN_DIR}"/bing*.xml
rm "${PLUGIN_DIR}"/eBay*.xml
rm "${PLUGIN_DIR}"/yahoo*.xml
set -e
# Remove unwanted iceweasel search plugins.
echo "Removing unwanted iceweasel search plugins"
rm /etc/iceweasel/searchplugins/common/duckduckgo.xml
rm /etc/iceweasel/searchplugins/locale/*/amazon*.xml
rm /etc/iceweasel/searchplugins/locale/*/answers.xml
rm /etc/iceweasel/searchplugins/locale/*/bing*.xml
rm /etc/iceweasel/searchplugins/locale/*/eBay*.xml
rm /etc/iceweasel/searchplugins/locale/*/yahoo*.xml
set -e
# Build binary sqlite iceweasel files from plain text SQL files.
echo "Building iceweasel sqlite files"
[ -d "${SQL_SRC_DIR}" ] || exit 11
apt-get install --yes $INSTALLED_PACKAGES
for sql_src_file in ${SQL_SRC_DIR}/*.sql ; do
db="$(basename ${sql_src_file} | sed -e 's|\.sql$||')"
sqlite3 "${dst_file}" < "${sql_src_file}"
rm -rf ${SQL_SRC_DIR}
apt-get --yes purge $INSTALLED_PACKAGES
......@@ -6,5 +6,5 @@ echo "Overriding TBB branding with our own"
install --owner root --group root --mode 0755 --directory /etc/xul-ext
install --owner root --group root --mode 0644 \
/etc/iceweasel/profile/extensions/ \
/etc/tor-browser/profile/extensions/ \
set -e
echo "Setting up localized browser search plugins"
# Link localized Tails searchplugins to the proper localization directories:
# e.g. files in '/usr/share/amnesia/browser/searchplugins/locale/es' will be
# linked in '/etc/tor-browser/profile/searchplugins/locale/es-AR',
# '/etc/tor-browser/profile/searchplugins/locale/es-ES', etc.
locales_for_lang() {
local locale="$1"
local langpacks
find /usr/local/lib/tor-browser/extensions -maxdepth 1 -type f -name 'langpack-*' -printf "%P\n" |
sed -n -e "s/^langpack-\($locale\)\(-[A-Z]\+\)\?\1\2/p"
for LANGUAGE in $(find /usr/share/amnesia/browser/searchplugins/locale -maxdepth 1 -type d -printf "%P\n"); do
LOCALES="$(locales_for_lang "$LANGUAGE")"
if [ -z "$LOCALES" ]; then
echo "Unable to find a matching locale for $LANGUAGE." >&2
exit 1
for LOCALE in $LOCALES; do
mkdir -p /usr/local/lib/tor-browser/Browser/distribution/searchplugins/locale/$LOCALE
for SEARCHPLUGIN in $(find "/usr/share/amnesia/browser/searchplugins/locale/$LANGUAGE" -maxdepth 1 -type f); do
ln -s "$SEARCHPLUGIN" /usr/local/lib/tor-browser/Browser/distribution/searchplugins/locale/$LOCALE
set -e
echo "Setting up localized iceweasel search plugins"
# Link localized Tails searchplugins to the proper localization directories:
# e.g. files in '/usr/share/amnesia/iceweasel/searchplugins/locale/es' will be
# linked in '/etc/iceweasel/searchplugins/locale/es-AR',
# '/etc/iceweasel/searchplugins/locale/es-ES', etc.
locales_for_lang() {
local locale="$1"
local langpacks
find /usr/lib/iceweasel/browser/extensions -maxdepth 1 -type f -name 'langpack-*' -printf "%P\n" |
sed -n -e "s/^langpack-\($locale\)\(-[A-Z]\+\)\?\1\2/p"
for LANGUAGE in $(find /usr/share/amnesia/iceweasel/searchplugins/locale -maxdepth 1 -type d -printf "%P\n"); do
LOCALES="$(locales_for_lang "$LANGUAGE")"
if [ -z "$LOCALES" ]; then
echo "Unable to find a matching locale for $LANGUAGE." >&2
exit 1
for LOCALE in $LOCALES; do
mkdir -p /etc/iceweasel/searchplugins/locale/$LOCALE
for SEARCHPLUGIN in $(find "/usr/share/amnesia/iceweasel/searchplugins/locale/$LANGUAGE" -maxdepth 1 -type f); do
ln -s "$SEARCHPLUGIN" /etc/iceweasel/searchplugins/locale/$LOCALE
echo "Generating iceweasel profile"
#generate iceweasel profile at build time, so that it has a fixed name
set -e
apt-get --yes install xvfb
TOR_SOCKS_HOST='' TOR_SOCKS_PORT='9151' xvfb-run /usr/bin/iceweasel -CreateProfile default
mv ~/.mozilla/firefox/*.default ~/.mozilla/firefox/default
sed -i "s@Path=.*\.default@Path=default@" ~/.mozilla/firefox/profiles.ini
mv ~/.mozilla /etc/skel
apt-get --yes purge xvfb
echo "Generating Tor Browser profile"
# Generate Tor Browser profile at build time so it won't reside in RAM
set -e
mv ~/.tor-browser /etc/skel
echo "Creating symbolic link for potentially persistent iceweasel bookmarks"
echo "Creating symbolic link for potentially persistent browser bookmarks"
#create a symlink to places.sqlite in iceweasel profile
#create a symlink to places.sqlite in browser profile
#from a dedicated "bookmarks" directory, so that
#it can be easily made persistent
set -e
ln -s /home/amnesia/.mozilla/firefox/bookmarks/places.sqlite /etc/skel/.mozilla/firefox/default/places.sqlite
mkdir /etc/skel/.mozilla/firefox/bookmarks
ln -s /home/amnesia/.mozilla/firefox/bookmarks/places.sqlite /etc/skel/.tor-browser/profile.default/places.sqlite
mkdir -p /etc/skel/.mozilla/firefox/bookmarks
......@@ -31,12 +31,11 @@ done
# Launcher is still running, we can just kill it and make sure it
# won't start next network reconnect. A reason for this happening is
# if Tor was restarted by tordate, e.g. if the clock was to incorrect.
if pgrep -f "iceweasel --app.*tor-launcher-standalone"; then
pkill -f "iceweasel --app.*tor-launcher-standalone"
for p in /home/tor-launcher/.torproject/torlauncher/*.default/prefs.js; do
sed -i '/^user_pref("extensions.torlauncher.prompt_at_startup"/d' "${p}"
echo 'user_pref("extensions.torlauncher.prompt_at_startup", false);' >> "${p}"
if pgrep -f "firefox --app.*tor-launcher-standalone"; then
pkill -f "firefox --app.*tor-launcher-standalone"
sed -i '/^user_pref("extensions.torlauncher.prompt_at_startup"/d' "${pref}"
echo 'user_pref("extensions.torlauncher.prompt_at_startup", false);' >> "${pref}"
/usr/local/sbin/tails-notify-user \
......@@ -35,7 +35,7 @@ domain ip {
mod owner uid-owner proxy ACCEPT;
mod owner uid-owner nobody ACCEPT;
daddr proto tcp syn mod multiport destination-ports (9050 9061 9062 9151) {
daddr proto tcp syn mod multiport destination-ports (9050 9061 9062 9150) {
mod owner uid-owner amnesia ACCEPT;
daddr proto tcp syn dport 9062 {
# Default Preferences
# Tor Browser Bundle
# Do not edit this file.
// Disable browser auto updaters and associated homepage notifications
pref("", false);
pref("app.update.enabled", false);
pref("", false);
pref("browser.rights.3.shown", true);
pref("browser.startup.homepage_override.mstone", "ignore");
pref("startup.homepage_welcome_url", "");
pref("startup.homepage_override_url", "");
// Disk activity: Disable Browsing History Storage
pref("browser.privatebrowsing.autostart", true);
pref("browser.cache.disk.enable", false);
pref("browser.cache.offline.enable", false);
pref("dom.indexedDB.enabled", false);
pref("permissions.memory_only", true);
pref("network.cookie.lifetimePolicy", 2);
pref("", 1);
// Disk activity: TBB Directory Isolation
pref("", false);
pref("", false);
pref("", false);
// Misc privacy: Disk
pref("signon.rememberSignons", false);
pref("browser.formfill.enable", false);
pref("signon.autofillForms", false);
pref("browser.sessionstore.privacy_level", 2);
pref("media.cache_size", 0);
// Misc privacy: Remote
pref("browser.send_pings", false);
pref("geo.enabled", false);
pref("geo.wifi.uri", "");
pref("", false);
pref("browser.safebrowsing.enabled", false);
pref("browser.safebrowsing.malware.enabled", false);
pref("", false); // prevents AV remote reporting of downloads
pref("extensions.ui.lastCategory", "addons://list/extension");
pref("datareporting.healthreport.service.enabled", false); // Yes, all three of these must be set
pref("datareporting.healthreport.uploadEnabled", false);
pref("datareporting.policy.dataSubmissionEnabled", false);
pref("security.mixed_content.block_active_content", false); // Disable until is patched
pref("browser.syncPromoViewsLeftMap", "{\"addons\":0, \"passwords\":0, \"bookmarks\":0}"); // Don't promote sync
pref("services.sync.engine.prefs", false); // Never sync prefs, addons, or tabs with other browsers
pref("services.sync.engine.addons", false);
pref("services.sync.engine.tabs", false);
pref("extensions.getAddons.cache.enabled", false); //
// Fingerprinting
pref("webgl.min_capability_mode", true);
pref("webgl.disable-extensions", true);
pref("dom.battery.enabled", false); // fingerprinting due to differing OS implementations
pref("",false); // fingerprinting due to differing OS implementations
pref("gfx.downloadable_fonts.fallback_delay", -1);
pref("general.appname.override", "Netscape");
pref("general.appversion.override", "5.0 (Windows)");
pref("general.oscpu.override", "Windows NT 6.1");
pref("general.platform.override", "Win32");
pref("general.useragent.override", "Mozilla/5.0 (Windows NT 6.1; rv:24.0) Gecko/20100101 Firefox/24.0");
pref("general.productSub.override", "20100101");
pref("general.buildID.override", "20100101");
pref("browser.startup.homepage_override.buildID", "20100101");
pref("general.useragent.vendor", "");
pref("general.useragent.vendorSub", "");
pref("dom.enable_performance", false);
pref("plugin.expose_full_path", false);
pref("browser.zoom.siteSpecific", false);
pref("intl.charset.default", "windows-1252");
pref("", 0); // Bug 9881: Open popups in new tabs (to avoid fullscreen popups)
// pref("intl.accept_languages", "en-us, en"); // Set by Torbutton
// pref("intl.accept_charsets", "iso-8859-1,*,utf-8"); // Set by Torbutton
// pref("intl.charsetmenu.browser.cache", "UTF-8"); // Set by Torbutton
// Third party stuff
pref("network.cookie.cookieBehavior", 1);
pref("security.enable_tls_session_tickets", false);
pref("network.http.spdy.enabled", false); // Stores state and may have keepalive issues (both fixable)
pref("network.http.spdy.enabled.v2", false); // Seems redundant, but just in case
pref("network.http.spdy.enabled.v3", false); // Seems redundant, but just in case
// Proxy and proxy security
pref("network.proxy.socks", "");
pref("network.proxy.socks_port", 9150);
pref("network.proxy.socks_remote_dns", true);
pref("network.proxy.no_proxies_on", ""); // For fingerprinting and local service vulns (#10419)
pref("network.proxy.type", 1);
pref("", "9050,9051,9150,9151");
pref("network.dns.disablePrefetch", true);
pref("network.protocol-handler.external-default", false);
pref("network.protocol-handler.external.mailto", false);
pref("", false);
pref("network.protocol-handler.external.nntp", false);
pref("network.protocol-handler.external.snews", false);
pref("network.protocol-handler.warn-external.mailto", true);
pref("", true);
pref("network.protocol-handler.warn-external.nntp", true);
pref("network.protocol-handler.warn-external.snews", true);
pref("plugins.click_to_play", true);
pref("plugin.state.flash", 1);
pref("plugins.hide_infobar_for_missing_plugin", true);
pref("media.peerconnection.enabled", false); // Disable WebRTC interfaces
// Network and performance
pref("network.http.pipelining", true);
pref("network.http.pipelining.aggressive", true);
pref("network.http.pipelining.maxrequests", 12);
pref("network.http.pipelining.ssl", true);
pref("network.http.proxy.pipelining", true);
pref("security.ssl.enable_false_start", true);
pref("network.http.keep-alive.timeout", 20);
pref("network.http.connection-retry-timeout", 0);
pref("network.http.max-persistent-connections-per-proxy", 256);
pref("network.http.pipelining.reschedule-timeout", 15000);
pref("", 60000);
// Hacked pref: Now means "Attempt to pipeline at least this many requests together"
pref("network.http.pipelining.max-optimistic-requests", 3);
// Extension support
pref("extensions.autoDisableScopes", 0);
pref("extensions.bootstrappedAddons", "{}");
pref("extensions.checkCompatibility.4.*", false);
pref("extensions.databaseSchema", 3);
pref("extensions.enabledAddons", ",%7B73a6fe31-595d-460b-a920-fcc0f8843232%7D:,,,,%7B972ce4c6-7e08-4474-a285-3208198ce6fd%7D:17.0.5");
pref("extensions.enabledItems", ",{73a6fe31-595d-460b-a920-fcc0f8843232}:,{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.2.4,{972ce4c6-7e08-4474-a285-3208198ce6fd}:3.5.8");
pref("extensions.enabledScopes", 1);
pref("extensions.pendingOperations", false);
pref("xpinstall.whitelist.add", "");
pref("xpinstall.whitelist.add.36", "");
// Omnibox settings
pref("keyword.URL", "");
// Hacks/workarounds: Direct2D seems to crash w/ lots of video cards w/ MinGW?
// Nvida cards also experience crashes without the second pref set to disabled
pref("gfx.direct2d.disabled", true);
pref("layers.acceleration.disabled", true);
// Security enhancements
pref("javascript.options.ion.content", false);
pref("javascript.options.baselinejit.content", false);
pref("javascript.options.asmjs", false);
pref("javascript.options.typeinference", false);
// Audio_data is deprecated in future releases, but still present
// in FF24. This is a dangerous combination (spotted by iSec)
pref("media.audio_data.enabled", false);
// Enable TLS 1.1 and 1.2:
pref("security.tls.version.max", 3);
// Version placeholder
pref("torbrowser.version", "UNKNOWN");
// This is the Debian specific preferences file for Iceweasel
// You can make any change in here, it is the purpose of this file.
// You can, with this file and all files present in the
// /etc/iceweasel/pref directory, override any preference that is
// present in /usr/lib/iceweasel/defaults/preferences directory.
// While your changes will be kept on upgrade if you modify files in
// /etc/iceweasel/pref, please note that they won't be kept if you
// do make your changes in /usr/lib/iceweasel/defaults/preferences.
// Note that lockPref is allowed in these preferences files if you
// don't want users to be able to override some preferences.
// Use LANG environment variable to choose locale
pref("intl.locale.matchOS", true);
// Extension support
pref("xpinstall.whitelist.add.103", "");
// Unsorted prefs
pref("network.cookie.prefsMigrated", true);
pref("spellchecker.dictionary", "en_US");
<SearchPlugin xmlns="" xmlns:os="">
<os:ShortName>DuckDuckGo HTML</os:ShortName>
<os:Description>Search DuckDuckGo (non-JS)</os:Description>