Sju bra saker att kunna när du jobbar i Linux-miljö
Den här listan är i första hand till för dig som jobbar med utveckling under Linux (i första hand Ubuntu), och behöver göra lite systemadministration till husbehovs på utvecklingsservern.
1. Lägga till användare och grupper (och lite om sudo)
Om du har fått ansvaret för en utvecklingsserver så innebär antagligen att du antingen fått tillgång till root-användaren, eller en egen användare med ”sudo-rättigheter”. Jag utgår från att du känner till att root är ”superuser”, med alla rättigheter. Sudo, däremot, är lite speciellt. Det betyder ”kör följande kommando som root-användare”. Sudo kommer då, om du har rättighet att använda det, fråga efter ditt lösenord — inte root-lösenordet — och sedan köra kommandot som följer, med root-rättigheter.
Du behöver köra som root, eller via sudo, för de allra flesta administrationsuppgifter du kan vilja göra. En av dessa som du säkert behöver göra är att skapa fler användare till ditt team, och kanske ge sudo-rättigheter till några av dem.
Skapa en användare är enkelt med ”adduser ”. Svara på frågorna som dyker upp sedan. För att skapa en användargrupp, t.ex. för att reglera åtkomsten för vissa filer eller repositoryn till en projektgrupp, kör du motsvarande ”addgroup ”. För att sedan lägga till en befintlig användare till en befintlig grupp kör du ”adduser ” så är det ordnat.
Om du vill skapa en ny användare med sudo-rättigheter så handlar det antagligen om att lägga till användaren till en viss grupp, troligen gruppen ”admin”. Kolla i /etc/sudoers så kan du nog räkna ut vilken grupp som har sudo-rättigheter.
2. Hålla systemet uppdaterat med apt-get
Pakethanteringen i Ubuntu och andra Debian-derivat, sköts med apt-get och kringkommandon. Här är några av de viktigaste saker du kan tänkas behöva göra.
Innan du gör något annat vill du antagligen först se till att den lokala kopian av paketindexet är aktuellt. Det gör du med (som root, som med alla apt-get-kommandon):
apt-get update
Ingenting installeras alltså, du uppdaterar bara paketindexet från paketservrarna.
Därefter kan du installera valfria Ubuntu-paket med:
apt-get install <paketnamn>
Men hur tar du reda på vilka paket som finns? Du kan googla, naturligtvis, men från kommandoprompten kan du också köra
apt-cache search mysql
Du får nu upp en lista på alla paket som har ordet ”mysql” i namnet eller beskrivningen. Den första kolumnen i listan är paketnamnet som du ska använda vid installation, t.ex:
apt-get install mysql-server
Pakethanteraren håller koll på alla beroenden som finns mellan paket, och det kan visa sig att installation av ett paket drar med sig dussintals andra, som det behöver. Om du vill se vad som kommer att hända, utan att installera något, kan du ”simulera” installationen genom att skicka med ”-s”-flaggan:
apt-get -s install tomcat6
Jag har för vana att alltid först köra ett apt-get-kommando med ”-s”-flaggan för att se om det är några överraskningar, och kan rekommendera den vanan!
De paket som du har installerade kommer regelbundet i uppdaterade versioner, och det kan vara viktigt ur säkerhetssynpunkt att se till att man får med de senaste uppdateringarna. Det här kommandot uppgraderar alla installerade paket till den senaste versionen:
apt-get dist-upgrade
Även detta kan köras med ”-s”-flaggan först, för att få se vad som kommer att hända:
apt-get -s dist-upgrade
Slutligen: det kan ofta vara intressant att se vilka paket man har installerade. Det görs enkelt med:
dpkg -l
Det resulterar troligen i en rätt lång lista, men med grep kan du plocka ut informationen du specifik vill ha, t.ex. alla mysql-relaterade paket:
dpkg -l | grep mysql
3. Inloggning utan lösenord
När du loggar in på servern är det nästan helt säkert ssh du använder. När du loggar in måste du normalt ange lösenord till användaren du loggar in till. Det kan snabbt bli ett irritationsmoment när du måste logga in flera ggr per dag, eller kanske flera ggr per timme, till olika servrar. Lösenordet måste ju vara kryptiskt för att vara säkert och det blir ofta fel.
Lösningen består i att sätta upp lösenordsfri inloggning. Det betyder inte att man slänger säkerheten överbord och låter vem som helst logga in utan att ange lösenord. I själva verket blir säkerheten mycket bättre! Du använder istället en kryptografiskt säker nyckel som i praktiken inte kan knäckas med brute-force-metoder. Det är väldigt enkelt att sätta upp och underlättar det vardagliga jobbet väldigt mycket, så det är väl värt tiden att lära sig hur det går till.
Antag att du har en användare ”a@client” som ska kunna logga in som användare ”b@server” utan att ange lösenord. Först generar vi ett nyckel-par på klienten:
a@client:~$ ssh-keygen
Tryck bara return på alla frågor (välj default, och se till att du inte anger någon lösenordsfras här). Nu kommer två filer att ha skapats i katalogen .ssh under din hemkatalog: id_rsa och id_rsa.pub. Dessa innehåller den privata och publika kryptonyckeln. Den privata ska hållas hemlig och får bara vara åtkomlig av ägande användare, medan den publika ska kopieras över till de servrar som den här användaren ska kunna logga in på. Den publika nyckeln ska ligga på en rad i serverns .ssh/authorized_keys. Där kan det ligga flera nycklar, om du vill kunna komma åt serverkontot från flera olika klienter och/eller användare.
Du kan absolut kopiera över innehållet manuellt, men ssh kommer med ett skript som gör det åt dig: ssh-copy-id:
a@client:~$ ssh-copy-id -i b@server
Skriptet kräver att du anger lösenordet till b@server, men det är sista gången du behöver det. Din publika nyckel från .ssh/id_rsa.pub kopieras över till .ss/authorized_keys på servern (som skapas om den inte redan finns).
Ovanstående instruktioner kan du använda om klienten är ett linux- eller mac-system, eller om du kör Cygwin under Windows. Använder du PuTTY under Windows så finns det instruktioner här.
4. Sätta upp en enkel brandvägg med iptables
Att sätta upp en server utan en brandvägg känns lite som att inte låsa dörren hemma när man ska åka på semester. Det är nog lugnt, men man kommer att sova dåligt på nätterna, och i värsta fall kan det gå riktigt illa. Vi sätter upp en rudimentär iptables-brandvägg istället så slipper vi tänka på det.
Se till att iptables finns installerat, eller installera det med apt-get enligt ovan. Paketet heter helt enkelt ”iptables”. Kör sedan följande kommandon efter varandra (rader som börjar med ”#” är kommentarer och behöver inte skrivas in, men det gör inget om de kommer med om du klipper och klistrar in i bash-prompten). Du måste vara root när du kör dem, eller använda sudo:
Ta bort eventuella gamla iptables-regler
iptables -F
# Acceptera allt som kommer från localhost
iptables -A INPUT -i lo -j ACCEPT
# Acceptera kopplingar som är relaterade till befintliga kopplingar
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Öppna för ssh och web utifrån
iptables -A INPUT -p tcp --dport ssh -j ACCEPT
iptables -A INPUT -p tcp --dport www -j ACCEPT
# Gör det möjligt att pinga servern
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
# Förbjud allt annat
iptables -A INPUT -j DROP
Nu är servern säkrad på enklaste nivån. Vill du ta bort brandväggen temporärt för att testa något specifikt så är det ”iptables -F” som ska köras igen. Observera dock att dessa kommandon inte gör så att brandväggen sparas undan på något sätt — den gäller bara tills servern startas om nästa gång! Men eftersom det är så sällan det finns anledning att starta om servern så lämnar jag nästa steg (att automatiskt lägga in brandväggen vid omstart) som en övning åt läsaren..!
5. Sätta upp ett Subversion-repository
Man kan sätta upp ett Subversion-repository på flera olika sätt, för att stödja olika typer av åtkomstmetoder, men det enklaste är att bara gå via ssh (utan lösenord, om du satt upp det enligt tidigare tips).
Först skapar du repositoryt. Jag brukar lägga det under /var/lib/svn/, så här:
robu@server:~$ sudo svnadmin create /var/lib/svn/exampleproject
Nu är det egentligen klart, men för att det ska bli riktigt användbart måste du trixa lite med filrättigheterna. Vi vill till exempel att bara vissa utpekade användare ska kunna komma åt repositoryt. Vi skapar då en grupp som ska innehålla dessa:
robu@server:~$ sudo addgroup exampleproject
Sedan lägger vi till var och en av de användare som ska tillhöra gruppen:
robu@server:~$ sudo adduser robu exampleproject
Vi ändrar sedan gruppägarskapet på alla filer i repositoryt, och sätter rätt rättigheter:
robu@server:~$ sudo chown -R :exampleproject /var/lib/svn/exampleproject
robu@server:~$ sudo chmod -R g+rws /var/lib/svn/exampleproject
Repositoryt är nu klart, men vi vill avrunda med ett sista steg. ”Best Practices” för Subversion säger att varje projekt i ett repository ska ha en projekt-rot-katalog som innehåller exakt tre kataloger: /trunk, /tags och /branches. Eftersom jag föredrar att ha ett projekt per repository (så långt det är praktiskt möjligt) så skapar vi de tre katalogerna direkt i roten:
robu@server:~$ export SVN_REPO=file:///var/lib/svn/exampleproject
robu@server:~$ svn mkdir $SVN_REPO/trunk $SVN_REPO/tags $SVN_REPO/branches -m "initial directory structure"
Repositoryt är nu färdigt att användas. Checka ut det tomma repositoryt från klienten och börja jobba:
robert@client:~$ svn co svn+ssh://robu@server/var/lib/svn/exampleproject/trunk exampleproject
6. Installera och växla mellan flera JDKer
Ofta kan det finnas skäl att installera flera versioner av Java (eller annat verktyg, för den delen, men här håller vi oss till JDKet). För att installera t.ex. version 5 och 6 av Suns JDK kör du:
robu@server:~$ sudo apt-get install sun-java5-jdk sun-java6-jdk
Du kommer att behöva godkänna licensen vid installationen, men i övrigt är det inga konstigheter. Nästa fråga kommer man till när man vill välja vilken av dessa som ska vara default vid ett givet tillfälle. Här finns det ett system i Ubuntu som håller koll på, och låter dig välja mellan, flera versioner av samma ”tjänst”, t.ex. JDK. Detta görs genom en sinnrik kedja av länkar, från /usr/bin/java, till en ”mellanplats” under /etc/alternatives, vidare till det ställe där verktygen faktiskt är installerade. För att byta dessa länkar och välja vilken version du vill använda kan du köra:
robu@server:~$ sudo update-alternatives --config java
Du kommer då att få en lista över de alternativ som finns installerade och kan välja vilket som ska gälla.
7. Sätta upp en virtual host med reverse proxy i apache2
Om det är en webbapplikation du utvecklar, vilket inte är helt otroligt, så är följande scenario vanligt: applikationen du utvecklar kör på en egen plattform, till exempel Tomcat för Java-applikationer. Helst vill du ju köra allt på port 80 eftersom det är där det ska ligga när det är klart, men istället för att ställa om tomcat att lyssna på den porten (istället för 8080 som är standard) finns det flera bra anledningar att låta apache httpd ligga mellan port 80 och den slutgiltiga destinationen. Jag ska inte försöka mig på en lista här, men en anledning är i alla fall att låta samma server ta hand om flera applikationer, beroende på vilket hostname man anger i URLen när man anropar den. Det kallas för en ”virtual host”, och tomcat kan också hantera det, men det förutsätter att alla applikationer bor i samma tomcat-instans.
Det sätt som jag föredrar är att installera apache2-paketet och låta den fungera som ”reverse proxy”.
Vi antar att du har en server på IP-adressen 123.123.123.123 och vill köra en tomcat-applikation på den som går att komma åt på http://kundapp.cygni.se. Tomcat lyssnar på sin default-port (8080) och applikationen är installerad i root-contextet. Nu vill vi ha en apache som tar hand om anrop på port 80 men skickar alla som går till domänen kundapp.cygni.se vidare till tomcat.
Installera först apache, om det inte är gjort:
robu@server:~$ sudo apt-get install apache2
När installationen är klar så snurrar apache och visar sin default-sida om du surfar in på servern med en vanlig webbläsare.
Apaches konfigurationsfiler ligger under /etc/apache2. Där hittar du också två kataloger som vi vill titta i: sites-available och sites-enabled. I sites-available lägger du en fil för varje virtual host som du vill att apache ska hantera. Från början ligger bara en fil där, ”default”, som hanterar alla anrop.
Skapa en ny fil i sites-available, som heter ”kundapp”, med följande innehåll:
<VirtualHost *:80>
ServerName kundapp.cygni.se
ServerAlias *.kundapp.cygni.se
ProxyRequests Off
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
</VirtualHost>
Nu måste du skapa sedan en länk till denna fil från katalogen sites-enabled, och säga till apache att ladda om sin konfigurering. Länken kan skapas helt manuellt, men det följer med ett skript, a2ensite, som hjälper dig. Då behöver du bara ange namnet på siten (filen du just skapat). Kör du a2ensite utan parametrar får du en lista på möjliga val.
robu@server:/etc/apache2/sites-enabled$ sudo a2ensite kundapp
robu@server:/etc/apache2/sites-enabled$ sudo /etc/init.d/apache2 reload
Nu kommer alla anrop som kommer in på servern 123.123.123.123 OCH som är adresserade till kundapp.cygni.se att skickas vidare till tomcat. Om det är en annan domän som efterfrågas på samma server så kan du skicka det till en annan applikation (genom att upprepa ovanstående uppsättning) eller så hanteras det av default-filen som innan.
Om det skulle vara så att det fortfarande inte fungerar så kan det bero på att apache inte har slagit på proxy-funktionaliteten. Det går till på ungefär samma sätta som att slå på en virtual host, enligt ovan. De moduler som finns ligger i /etc/apache2/mods-available, och de som har slagits på ligger som länkar under /etc/apache2/mods-enabled. Du bör ha länkar till ”proxy.conf”, ”proxy_http.load” och ”proxy.load” i mods-enabled. Har du inte det så lägg till dem så här, och starta om apache (vi oss använder även här av hjälpskripten som följer med apache):
robu@server:/etc/apache2/mods-enabled$ sudo a2enmod proxy
robu@server:/etc/apache2/mods-enabled$ sudo a2enmod proxy_http robu@server:/etc/apache2/mods-enabled$ sudo /etc/init.d/apache2 restart
Ja, det var allt jag hade tänkt tipsa om idag. Självklart finns det oerhört mycket mer, men det här kände jag var sju bra saker att ha koll på om man ska utveckla i Linux-miljö, vilket är en vanlig situation för oss. Har jag missat nåt viktigt? Finns det enklare sätt att göra det jag beskriver? Vad är dina favorit-tips som du tror inte alla känner till? Vad ska jag ha med i nästa lista? Kommentera nedan!