Intranet/Intranet Reference Build Ubuntu
This page documents the OS and initial configuration that is used and tested against within this series of articles. The focus is on a system that will work in the vast majority of corporate environments that make use of Active Directory. All of these steps have been tested on a real system. The following table shows when it was last tested.
Date | Notes |
---|---|
03 Jun 2023 | Running Ubuntu Focal (20.04). I don't recall any major issues. I believe the config here is all still current. |
The commands shown do not have sudo preceding them. Either put sudo on the front of each command that has a # prompt or run sudo -i first and provide your password to run an interactive shell as root.
Hardware
editSee screenshot. There are no hard and fast rules and here we are using a virtual machine with some suggested minimums.
OS
editInitial Installation
edit- Ubuntu 20.04 LTS minimal https://help.ubuntu.com/community/Installation/MinimalCD
- Static IP address
- Guided partitioning with LVM, suggested start off with at least 30GB disc space
- Initial Unix username should not match any username in Active Directory. local-sysadmin might make a good choice
- Only add OpenSSH server role
Internet access via a web proxy
editIf www access must be via a proxy, then during the installation, when prompted enter a proxy URL similar to these. EXAMPLE is the domain name and %5C is the encoding for "\". The port number after the colon ":" is likely to be either 8080 or 3128. proxyuser and proxypassword should be set accordingly.
- NTLM authentication
http://EXAMPLE%5Cproxyuser:proxypassword@proxy.example.co.uk:8080
- Basic authenticationThis will set up APT to always use the proxy. See /etc/apt/apt.conf where the proxy setting is enabled, after installation.
http://proxyuser:proxypassword@proxy.example.co.uk:8080
Basic additions
editVM Guest tools (for virtual machine) and ntp
edit# apt install open-vm-tools ntp
Ensure that ntp is able to see enough time sources. You could use use your AD DCs for example, especially the one with the PDC emulator role. For the reference /etc/ntp.conf, remove anything in the default file under # Specify one or more ... to the next comment block that starts #Access control. Then insert something like the following. These settings are suitable for an intranet with good communication speeds and will cause the clock to sync quite rapidly. "tinker panic 0" means that if the local clock is more than 30 seconds adrift it will still sync to the servers rather than declaring them insane!
# Specify one or more NTP servers.
# Allow a large offset
tinker panic 0
server ntp1.example.co.uk iburst
server ntp2.example.co.uk iburst
server ntp3.example.co.uk iburst
# fall back to local clock
server 127.127.1.0
fudge 127.127.1.0 stratum 14
# Access control configuration; see /usr/share/doc/ntp-doc/html/accopt.html for
# details. The web page <http://support.ntp.org/bin/view/Support/AccessRestrictions>
# might also be helpful.
# systemctl restart ntp
# ntpq -p
.... ntp status displayed ....
The reference system also gets these (optional) packages.
# apt install screen joe iotop htop
System proxy settings
editIf you need proxy settings then set the standard variables as follows in /etc/environment using the same settings as used above when installing the OS.
# /etc/environment
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games"
# Proxy variables - NTLM, %5C = "\"
http_proxy=http://EXAMPLE%5Cproxy:password@proxy.example.co.uk:8080
HTTP_PROXY=http://EXAMPLE%5Cproxy:password@proxy.example.co.uk:8080
https_proxy=http://EXAMPLE%5Cproxy:password@proxy.example.co.uk:8080
HTTPS_PROXY=http://EXAMPLE%5Cproxy:password@proxy.example.co.uk:8080
ftp_proxy=http://EXAMPLE%5Cproxy:password@proxy.example.co.uk:8080
FTP_PROXY=http://EXAMPLE%5Cproxy:password@proxy.example.co.uk:8080
no_proxy=localhost,127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16
CA SSL certificate
editThis will be necessary to use LDAPS against a domain controller, for example, without having to disable SSL checks:
- Export the AD CA certificate as Base 64 encoded. Its name must end in .crt.
- You may be able to download a copy of the CA certificate by pointing a browser at https://ca.example.co.uk/certsrv if the CA's web service has been installed
- To find your CA you could try:
C:\> certutil -config - -ping
Another method to get the CA certificate. This will display the CA certificate and put it in a file called ca.crt:
C:\> certutil -ca.cert -config - ca.crt
- Copy ca.crt to /usr/local/share/ca-certificates The actual name used for the file is unimportant. You could simply copy the output and paste it into a blank new file instead. The certificate file should include the -----BEGIN CERTIFICATE ------ and -----END CERTIFICATE ----- lines.
- Run the following command. Also shown is a command to dump a list of all the CA certs that the system trusts. The new one should be listed at the bottom.
# update-ca-certificates
Updating certificates in /etc/ssl/certs...
1 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d...
done.
# openssl crl2pkcs7 -nocrl -certfile /etc/ssl/certs/ca-certificates.crt | openssl pkcs7 -print_certs -noout
Verify that you can connect to an AD Domain Controller's LDAP. Here we are connecting to the Global Catalogue over TLS (port 3269) you can also test against :636. There is a lot more output but at the end will be an indication about whether the CA certificate is trusted or not . Press CTRL-C to close the connection. This is an example of it not working:
$ openssl s_client -connect dc.example.co.uk:3269
....
Verify return code: 21 (unable to verify the first certificate)
---
Working:
$ openssl s_client -connect dc.example.co.uk:3269
....
Verify return code: 0 (ok)
---
Now is a good time to shutdown the VM and take a snapshot
Application software
editAD integration - Samba
editInstall software. acl will be used later in the build to make the system Kerberos keytab available to services as required.
# apt install winbind krb5-user acl
If prompted for a realm, type in the Active Directory domain name in CAPITALS. For example: EXAMPLE.CO.UK. By default, smbd and nmbd will be started. They are unnecessary for the purpose of running a wiki. Unless you want them running for fileserving, shut them down and then disable them:
# systemctl disable smbd nmbd
# systemctl stop smbd nmbd
Configure Samba by moving the default config file out of the way
# mv /etc/samba/smb.conf /etc/samba/smb.conf.DISTRO
Create a new /etc/samba/smb.conf. In the following reference config, you must set your workgroup and realm (AD). Also set the domain shortname (Netbios name) in the idmap config lines. The rest of the example can be used without change. Note that the min protocol set here will mean that Windows XP machines will be unable to access this system as a file server.
# /etc/samba/smb.conf
[global]
workgroup = EXAMPLE
realm = EXAMPLE.CO.UK
idmap config EXAMPLE : backend = rid
idmap config EXAMPLE : range = 10000 - 19999
server string = Samba Server
security = ADS
kerberos method = secrets and keytab
dedicated keytab file = /etc/krb5.keytab
winbind refresh tickets = true
obey pam restrictions = yes
local master = no
min protocol = SMB2
lanman auth = no
client NTLMv2 auth = yes
client lanman auth = no
client plaintext auth = no
ldap ssl = start tls
server signing = mandatory
logging = file
log level = 3 winbind:5
max log size = 1024
debug uid = yes
socket options = TCP_NODELAY IPTOS_LOWDELAY
printcap name = cups
idmap config * : backend = tdb
idmap config * : range = 1000000-1999999
template shell = /bin/bash
winbind enum users = yes
winbind enum groups = yes
winbind use default domain = yes
winbind offline logon = yes
winbind cache time = 60
guest account = nobody
map to guest = never
guest ok = no
Check that all is OK. This command should give sensible output.
# net ads info
LDAP server: <ip address of DC>
LDAP server name: <name of DC>
Realm: EXAMPLE.CO.UK
Bind Path: dc=EXAMPLE,dc=CO,dc=UK
LDAP port: 389
Server time: Mon, 06 Nov 2017 11:45:33 GMT
KDC server: <ip address of DC>
Server time offset: 0
Join the domain. "username" should be a user that has AD permissions to create a workstation object. DNS update errors are not fatal
# net join -U username # MAKE SURE YOU PUT YOUR AD USERNAME HERE #
Enter username's password:
Using short domain name -- EXAMPLE
Joined 'WIKI' to dns domain 'example.co.uk'
No DNS domain configured for wiki. Unable to perform DNS Update.
DNS update failed: NT_STATUS_INVALID_PARAMETER
Restart winbind and verify that the domain can be accessed and that Kerberos is working
# systemctl restart winbind
# wbinfo -u
... list of AD users ...
# net ads keytab list
... Kerberos keytab is displayed with around 15 entries ...
Winbind and NSS
editThis makes AD users into Unix users.
# apt install libnss-winbind libpam-winbind
Edit /etc/nsswitch.conf and add winbind
passwd: compat winbind
group: compat winbind
Verify it is working
# getent passwd
.... list of local Unix users followed by AD users ....
Create /etc/security/pam_winbind.conf
[global]
debug = yes
debug_state = no
try_first_pass = yes
krb5_auth = yes
krb5_ccache_type = file
cached_login = yes
silent = no
mkhomedir = yes
sudo
editWith this configuration, your initial Unix user can still login at the console of the system if AD is unavailable or networking is broken. sshd uses the "host" service principals which should already be in the keytab and because it runs as root it is able to read the keytab.
- Create a group in AD for users that will be able to run sudo on this system and add some users to it. I call mine sysadmin. It does not matter where the group is within the AD structure.
- Create a file called /etc/sudoers.d/local (the name is unimportant)
# local sudo config
# sysadmin is an AD group, wheel is a unix group
%wheel ALL=(ALL) ALL
%sysadmin ALL=(ALL) ALL
Kerberize ssh
editEdit /etc/ssh/ssh_config and uncomment and enable GSSAPI authentication. This is for using ssh on the system itself to another one
Host *
GSSAPIAuthentication yes
Edit /etc/sshd_config and enable GSSAPI authentication. Disable clear text passwords. I also recommend explicitly disabling RootLogin
PermitRootLogin no
PasswordAuthentication no
GSSAPIAuthentication yes
Restart the OpenSSH daemon
# systemctl restart sshd
You should now be able to ssh directly in as an AD user. A reasonably modern version of PuTTY can do this from a Windows workstation, provided GSSAPI is enabled and the tickbox to use the logged in username is ticked. Also bear in mind that Unix systems are case sensitive so you may have to reset the case on your Windows account's various naming attributes.
Database - MariaDB
editInstall software and secure it. The root password is initially blank so hit enter when prompted for the current root password. Note that user root in database is not the same as the user root in the Linux system, both simply have the same name. Keep a note of the password that you set.
# apt install mariadb-server
# mysql_secure_installation
Check that you can access the database server with the password you set earlier. Type \q and hit enter to exit.
# mysql -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
... copywrite notice etc ...
MariaDB [(none)]> \q
Bye
Webserver - Apache
editInstall basic software. Apache runs as the www-data user which can't access the Kerberos keytab by default so setfacl is used to allow it to read it. net ads keytab add is used to add a service principal for HTTP which is the default for Apache. The final command should list several entries starting HTTP/ . "AD_username" should be an account that has permissions to set service principals (Domain Admin??).
# apt install apache2 libapache2-mod-auth-kerb libapache2-mod-php
# a2enmod rewrite auth_kerb ssl ldap authnz_ldap
# a2ensite default-ssl
# setfacl -m u:www-data:r /etc/krb5.keytab
# net ads keytab add HTTP -U AD_username # MAKE SURE YOU SET YOUR AD USERNAME HERE #
# net ads keytab list
.... Kerberos keytab is displayed with more entries starting with HTTP/ ....
# systemctl restart apache2
The Apache installer will enable and start the web server. Point a browser at it and you should get the Ubuntu default page. You will get a certificate error in your browser when you test because the server is currently using a self signed certificate. Later on we will obtain a trusted certificate.
vhost with LDAP and Kerberos
edit- Remove all website configuration links (you could use the a2dissite command instead)
# rm /etc/apache2/sites-enabled/*
- Create a user in AD, which in this example is called ldapsearch. It only needs enough rights to connect and read public attributes.
- Create a new website configuration. Ensure you make the required changes for your environment. You put this file in the sites-available directory and then symlink it in the sites-enabled directory. The symlink command is listed after the config example.
To use this configuration as-is you must have client systems that are correctly setup to use Negotiate [1]. You could set KrbMethodK5Passwd On which will enable the browser to prompt for a username and password. This configuration requires that all users of the wiki should be members of a particular AD group to even be able to connect to the webserver. The string of numbers before the group name enables this group to have nested groups.
You should make changes on the indicated lines. my_local_user is not used yet and can be left as is for now.
# /etc/apache2/sites-available/local.conf
# Require Kerberos authentication and LDAP authorisation and SSL for remote
# connections or if local, allow access and set REMOTE_USER
ServerName wiki.example.co.uk
<VirtualHost _default_:443>
ServerAdmin webmaster@example.co.uk
DocumentRoot /var/www/html
SSLEngine on
SSLProtocol all -SSLv2 -SSLv3 -TLSv1
SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-
SSLHonorCipherOrder on
SSLCompression off
SSLOptions +StrictRequire
SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
</VirtualHost>
LogLevel Debug
# Force https if remote
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteCond expr "!(%{REMOTE_ADDR} -ipmatch '127.0.0.1' || %{REMOTE_ADDR} -ipmatch '::1')"
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
# LDAP cache
LDAPSharedCacheSize 500000
LDAPCacheEntries 1024
LDAPCacheTTL 600
LDAPOpCacheEntries 1024
LDAPOpCacheTTL 600
<Location "/ldap-status">
SetHandler ldap-status
</Location>
<Location />
<If "%{REMOTE_ADDR} -ipmatch '127.0.0.1' || %{REMOTE_ADDR} -ipmatch '::1'">
SetEnv REMOTE_USER my_local_user
</If>
<RequireAny>
<RequireAll>
Require ip 127.0.0.1 ::1
Require not ssl
</RequireAll>
<RequireAll>
AuthType Kerberos
AuthName "Login"
KrbMethodNegotiate On
KrbMethodK5Passwd Off
KrbLocalUserMapping On
KrbAuthRealms EXAMPLE.CO.UK
Krb5KeyTab /etc/krb5.keytab
# AD Global Catalogue over SSL.
AuthLDAPURL "ldaps://dc1.example.co.uk:3269 \
dc2.example.co.uk:3269/?sAMAccountName?sub"
AuthLDAPBindDN "ldapsearch@example.co.uk"
AuthLDAPBindPassword "....... PASSWORD ......."
Require ssl
Require valid-user
Require ldap-filter \
memberof:1.2.840.113556.1.4.1941:=CN=A_USER_GROUP,OU=Groups,OU=My_Company,DC=Example,DC=co,DC=uk
</RequireAll>
</RequireAny>
</Location>
Enable the Apache site configuration:
# cd /etc/apache2/sites-enabled
# ln -s ../sites-available/local.conf ./
Create a simple testing php script at /var/www/html/index.php
<?php
echo $_SERVER['REMOTE_USER'];
phpinfo();
?>
Remove the default page so that index.php is executed instead.
# mv /var/www/html/index.html /var/www/html/index.html.DISTRO
Restart the web server
# systemctl restart apache2
Point a browser at http://wiki.example.co.uk and it should redirect you to https and output your username followed by phpinfo() - lots of handy debugging information. Ensure you are logged in as a member of the AD "A_USER_GROUP" group. When it is working, I suggest you delete or disable the index.php script.
AD CA signed SSL certificate
editYou will need a correctly setup Windows CA for this step and its root certificate installed in the local trust store for all clients that access this system. Chrome(ium), at least, requires a certificate has a Subject Alternative Name for the Common Name to be considered secure. There are several ways to do the job, here is one.
- Create a directory to hold the certificate related files, set permissions and cd into it.
# cd /etc/apache2
# mkdir ssl
# chmod o= ssl
# cd ssl
- Generate a CSR
Create a configuration file called /etc/apache2/ssl/csr.conf which will be used to override the system defaults. "CN =" is the Common Name which is the name that should match what is typed into the browser. "subjectAltName =" here, is a pointer to a list that is created under the [alt_names ] heading. You should put your own settings for everything under [ dn ], apart from CN you can put anything suitable.
# /etc/apache2/ssl/csr.conf
[req]
default_bits = 2048
prompt = no
default_md = sha256
req_extensions = req_ext
distinguished_name = dn
[ dn ]
C = GB
ST = County
L = Town
O = Example Company Name Ltd
CN = wiki.example.co.uk
[ req_ext ]
subjectAltName = @alt_names
[ alt_names ]
DNS.1 = wiki.example.co.uk
- Create a private key wiki.key and CSR wiki.csr.
# openssl req -new -sha256 -nodes -out wiki.csr -newkey rsa:2048 -keyout wiki.key -config csr.conf
- Obtain a certificate from an AD CA
Transfer wiki.csr to a Windows system that has the certreq command available You will need to run the following command as a user with the correct rights.
C:\> certreq -submit -attrib "Certificatetemplate:WebServer" wiki.csr wiki.crt
This will create wiki.crt.
- Install the certificate
Transfer wiki.crt to /etc/apache2/ssl. Edit the Apache configuration /etc/apache2/sites-available/local.conf to use the new SSL certificate
# /etc/apache2/sites-available/local.conf
...
SSLCertificateFile /etc/apache2/ssl/wiki.crt
SSLCertificateKeyFile /etc/apache2/ssl/wiki.key
...
Restart Apache and test with your browser. You should not get a certificate related security error.
Firewall - UFW
editThe Ubuntu minimal installer includes the Uncomplicated Firewall (UFW) which is a package to configure the standard iptables Linux firewall, and the reference build uses it as an additional layer of protection and to comply with likely corporate policy. By default ufw will allow outgoing connections and block incoming connections. These commands will allow access from anywhere to ssh and the web server and switch on the firewall.
# ufw allow "OpenSSH"
# ufw allow "Apache Secure"
# ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup
# ufw status verbose
Status: active
...
To Action From
-- ------ ----
22/tcp (OpenSSH) ALLOW IN Anywhere
443/tcp (Apache Secure) ALLOW IN Anywhere
22/tcp (OpenSSH (v6)) ALLOW IN Anywhere (v6)
443/tcp (Apache Secure (v6)) ALLOW IN Anywhere (v6)
Upgrading Xenial to Bionic
editSome quick notes that were needed for a successful upgrade of a MediaWiki 1.31 running on Ubuntu Xenial(16.04) to MediaWiki 1.33 on Bionic (18.04):
Enable PHP because it was disabled after the upgrade - the wiki home page came up in plain text:
# a2enmod php7.2
# systemctl restart apache2
Reinstall PHP-curl because it was held back to an older version for some reason: (The following packages have been kept back: php-curl)
# apt install php-curl
# systemctl restart apache2
Put back the Parsoid source because it was removed:
# apt-add-repository "deb https://releases.wikimedia.org/debian jessie-mediawiki main"
The upgrade was done by upgrading Mediawiki itself following the guide here Intranet/Intranet Installation after which the Visual Editor stopped working properly. After upgrading the OS from Xenial to Bionic and fixing PHP, Visual Editor worked again.
References
edit- ↑ Intranet/Intranet Client Configuration - Client browser configuration to support Negotiate