https://wiki.alpinelinux.org/w/api.php?action=feedcontributions&user=Aalatchm&feedformat=atomAlpine Linux - User contributions [en]2024-03-28T20:14:17ZUser contributionsMediaWiki 1.40.0https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_3.x_HowTo&diff=13288ISP Mail Server 3.x HowTo2017-04-13T16:17:56Z<p>Aalatchm: s/php/php5/</p>
<hr />
<div>{{Draft|This is a work in progress based on migrating alpinelinux mail servers to 3.x}}<br />
<br />
== A Full Service Mail Server ==<br />
<br />
This document describes installation process for the Alpine Linux 3.x platform. The goal of this document is to describe how to set up postfix, dovecot, clamav, dspam, roundecube, and postfixadmin for a full-featured "ISP" level mail server. This document superceeds the previous [[ISP Mail Server 2.x HowTo]] instructions for Alpine 2.x. For this guide, we start with a server ''without'' ACF installed.<br />
<br />
The server provides:<br />
<br />
* multiple virtual domains<br />
* admins for each domain (to add/remove virtual accounts)<br />
* quota support per domain / account<br />
* downloading email via IMAP / IMAPS / POP3 / POP3S<br />
* relaying email for authenticated users with TLS or SSL (Submission / SMTPS protocol)<br />
* standard filters (virus/spam/rbl/etc)<br />
* web mail client<br />
* value add services<br />
<br />
== Set up Lighttpd + PHP ==<br />
<br />
PostfixAdmin needs php pgpsql and imap modules, so we do it in this step.<br />
<br />
apk add lighttpd php php-cgi php-pgsql php-imap<br />
<br />
''looks like php5-* needed on alpine-3.4.6''<br />
<br />
We are setting this up to be a multi-domain virtual web server (replace host.example.com with the actual domain):<br />
<nowiki>mkdir -p /var/www/domains/host.example.com/www<br />
cat <<-EOF >/var/www/domains/host.example.com/www/index.html<br />
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><br />
<html lang="en"><br />
<head><br />
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><br />
<title>host.example.com Redirector</title><br />
</head><br />
<body><br />
<ul><br />
<li><a href="/postfixadmin">PostfixAdmin</a></li><br />
<li><a href="/roundcube">Roundcube</a></li><br />
</ul><br />
</body><br />
EOF<br />
</nowiki><br />
<br />
Get a web certificate, and install it. There are several options:<br />
# Use a self-signed certificate, such as [[Generating SSL certs with ACF]] <br />
# Use the certificate created with '''setup-acf''', if you installed ACF<br />
# Get a certificate from a trusted root Certificate Authority, such as StartSSL.com, Thawte.com, Verisign.com, etc.<br />
<br />
These instructions will use a certificate issued from a self-signed ACF based CA<br />
<br />
openssl pkcs12 -nokeys -cacerts -in certificate.pfx -out /etc/lighttpd/ca-crt.pem<br />
openssl pkcs12 -nodes -in certificate.pfx -out /etc/lighttpd/server-bundle.pem<br />
chown root:root /etc/lighttpd/server-bundle.pem<br />
chmod 400 /etc/lighttpd/server-bundle.pem<br />
<br />
'''Note:''' The server certificate ''and'' key are in the server-bundle.pem file, so it is critical that the file be read-only by user "root".<br />
<br />
Add these lines to /etc/lighttpd/lighttpd.conf to point to the new document root, and set it up to listen on port 443 (replace ''host.example.com'' with the actual domain and ''ip_address_of_server'' with the actual IP address):<br />
<br />
<pre><br />
<br />
simple-vhost.server-root = "/var/www/domains/"<br />
simple-vhost.default-host = "/host.example.com/"<br />
simple-vhost.document-root = "www/"<br />
<br />
$SERVER["socket"] == "ip_address_of_server:443" {<br />
ssl.engine = "enable"<br />
ssl.pemfile = "/etc/lighttpd/server-bundle.pem"<br />
ssl.ca-file = "/etc/lighttpd/ca-crt.pem"<br />
}<br />
</pre><br />
<br />
Ensure that the simple_vhosts module is loaded, as well as the cgi config scripts by uncommenting the following lines in /etc/lighttpd/lighttpd.conf:<br />
<br />
server.modules = (<br />
# other modules may be listed<br />
"mod_simple_vhost", <br />
# other modules may be listed<br />
.<br />
.<br />
.<br />
include "mod_fastcgi.conf"<br />
<br />
start lighttpd, test:<br />
<br />
rc-update add lighttpd<br />
rc<br />
<br />
At this point you should be able to see the redirect page: https://host.example.com/<br />
<br />
== Install Postgresql ==<br />
<br />
Add and configure postgresql:<br />
<br />
apk add postgresql postgresql-client<br />
/etc/init.d/postgresql setup<br />
/etc/init.d/postgresql start<br />
rc-update add postgresql<br />
<br />
At this point any user can connect to the sql server with "trust" mechanism. If you want to enforce password authentication (you probably do) edit /var/lib/postgresql/9.0/data/pg_hba.conf. Since by default "trust" mechanism is for local connections only we assume using trust password-less access as safe.<br />
<br />
Create the postfix database:<br />
<br />
psql -U postgres<br />
create user postfix with password '******';<br />
create database postfix owner postfix;<br />
\q<br />
<br />
(Of course, use your selected password where ******* is shown above.)<br />
<br />
== Install PostfixAdmin ==<br />
<br />
We are going to install the postfix admin web front-end before we install the mail server. This just creates an interface to populate the SQL tables that postfix and dovecot will use.<br />
<br />
Download PostfixAdmin from Sourceforge. When these instructions were written, 2.93 was the current release, so (replace host.example.com with the actual domain):<br />
<br />
wget http://downloads.sourceforge.net/project/postfixadmin/postfixadmin/postfixadmin-2.93/postfixadmin-2.93.tar.gz<br />
tar zxvf postfixadmin-2.93.tar.gz<br />
mkdir -p /var/www/domains/host.example.com/www/postfixadmin<br />
mv postfixadmin-2.3.3/* /var/www/domains/host.example.com/www/postfixadmin<br />
rm -rf postfixadmin*<br />
<br />
Edit /var/www/domains/host.example.com/www/postfixadmin/config.inc.php and modify at least these lines (replace host.example.com with the actual domain):<br />
<br />
$CONF['configured'] = true;<br />
$CONF['setup_password'] = ""; << Don't change this yet<br />
$CONF['database_type'] = 'pgsql';<br />
$CONF['database_host'] = 'localhost';<br />
$CONF['database_user'] = 'postfix';<br />
$CONF['database_password'] = '*****'; << The password you chose above<br />
$CONF['database_name'] = 'postfix';<br />
$CONF['database_prefix'] = "";<br />
$CONF['admin_email'] = 'you@some.email.com'; << Your email address <br />
$CONF['encrypt'] = 'dovecot:SHA512-CRYPT';<br />
$CONF['authlib_default_flavor'] = 'SHA';<br />
$CONF['dovecotpw'] = "/usr/bin/doveadm pw";<br />
$CONF['domain_path'] = 'YES';<br />
$CONF['domain_in_mailbox'] = 'NO';<br />
$CONF['aliases'] = '10'; <br />
$CONF['mailboxes'] = '10';<br />
$CONF['maxquota'] = '10';<br />
$CONF['quota'] = 'YES';<br />
$CONF['quota_multiplier'] = '1024000';<br />
$CONF['vacation'] = 'NO'; <br />
$CONF['vacation_control'] ='NO';<br />
$CONF['vacation_control_admin'] = 'NO';<br />
$CONF['alias_control'] = 'YES';<br />
$CONF['alias_control_admin'] = 'YES';<br />
$CONF['special_alias_control'] = 'YES';<br />
$CONF['fetchmail'] = 'NO';<br />
$CONF['user_footer_link'] = "http://host.example.com/postfixadmin";<br />
$CONF['footer_link'] = 'http://host.example.com/postfixadmin/main.php';<br />
$CONF['create_mailbox_subdirs_prefix']=""; <br />
$CONF['used_quotas'] = 'YES'; <br />
$CONF['new_quota_table'] = 'YES'; <br />
<br />
You should further edit /var/www/domains/host.example.com/www/postfixadmin/config.inc.php and replace all instances of "change-this-to-your.domain.tld" with your actual mail domain. This can be done with busybox sed (replace example.com with your domain name):<br />
<br />
sed -i -e 's/change-this-to-your.domain.tld/example.com/g' /var/www/domains/host.example.com/www/postfixadmin/config.inc.php<br />
<br />
Go to https://host.example.com/postfixadmin/setup.php<br />
<br />
Create the password hash, add it to the config.inc.php file<br />
<br />
Go back to https://host.example.com/postfixadmin/setup.php<br />
<br />
Create superadmin account.<br />
<br />
'''NOTE:''' Check http://sourceforge.net/tracker/index.php?func=detail&aid=2859165&group_id=191583&atid=937964 if you have bug on listing domains page.<br />
<br />
== Install Postfix ==<br />
<br />
<br />
Install postfix<br />
<br />
apk add postfix postfix-pgsql postfix-pcre<br />
<br />
The install should create a vmail user; you'll need the numeric uid/gid for the postfix main.cf file.<br />
<br />
grep vmail /etc/passwd<br />
<br />
(we will use 102:105 in the examples below)<br />
<br />
<br />
Create the mail directory, and assign vmail as the owner:<br />
<br />
mkdir -p /var/mail/domains<br />
chown -R vmail:postdrop /var/mail/domains<br />
<br />
Edit the /etc/postfix/main.cf file. Here's an example (don't forget to replace the uid/gid):<br />
<br />
# New install - don't need to be backward compatible <br />
compatibility_level = 2 <br />
<br />
myhostname=host.example.com<br />
mydomain=example.com<br />
<br />
mydestination = localhost.$mydomain, localhost<br />
mynetworks_style = subnet<br />
mynetworks = 127.0.0.0/8<br />
<br />
virtual_mailbox_domains = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_domains_maps.cf<br />
virtual_alias_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_maps.cf,<br />
proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_maps.cf,<br />
proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_catchall_maps.cf<br />
<br />
virtual_mailbox_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_mailbox_maps.cf,<br />
proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_mailbox_maps.cf<br />
<br />
virtual_mailbox_base = /var/mail/domains/<br />
virtual_gid_maps = static:105<br />
virtual_uid_maps = static:102<br />
virtual_minimum_uid = 100<br />
virtual_transport = virtual<br />
<br />
<br />
# This next command means you must create a virtual<br />
# domain for the host itself - ALL mail goes through<br />
# The virtual transport<br />
<br />
mailbox_transport = virtual<br />
local_transport = virtual<br />
local_transport_maps = $virtual_mailbox_maps<br />
<br />
smtpd_helo_required = yes<br />
disable_vrfy_command = yes<br />
<br />
# 100MB size limit<br />
message_size_limit = 104857600<br />
virtual_mailbox_limit = 104857600<br />
queue_minfree = 51200000<br />
<br />
smtpd_sender_restrictions =<br />
permit_mynetworks,<br />
reject_non_fqdn_sender,<br />
reject_unknown_sender_domain<br />
<br />
smtpd_recipient_restrictions =<br />
reject_non_fqdn_recipient,<br />
reject_unknown_recipient_domain,<br />
permit_mynetworks,<br />
permit_sasl_authenticated,<br />
reject_unauth_destination,<br />
reject_rbl_client dnsbl.sorbs.net,<br />
reject_rbl_client zen.spamhaus.org,<br />
reject_rbl_client bl.spamcop.net<br />
<br />
smtpd_data_restrictions = reject_unauth_pipelining<br />
<br />
# we will use this later - This prevents cleartext authentication<br />
# for relaying<br />
smtpd_tls_auth_only = yes<br />
<br />
# Silence the EAI warning on alpine linux<br />
smtputf8_enable = no<br />
<br />
Now we need to create a *bunch* of files so that postfix can get the delivery information out of sql. Here's a shell script to create the scripts. Change PGPW to the password for the postfix user of the postfix SQL database:<br />
<br />
cd /etc/postfix<br />
mkdir sql<br />
PGPW="ChangeMe"<br />
<br />
cat - <<EOF >sql/pgsql_virtual_alias_domain_catchall_maps.cf<br />
user=postfix<br />
password = $PGPW<br />
hosts = localhost<br />
dbname = postfix<br />
query = Select goto From alias,alias_domain where alias_domain.alias_domain = '%d' and alias.address = '@' || alias_domain.target_domain and alias.active = true and alias_domain.active= true <br />
EOF<br />
<br />
cat - <<EOF >sql/pgsql_virtual_alias_domain_mailbox_maps.cf<br />
user=postfix<br />
password = $PGPW<br />
hosts = localhost<br />
dbname = postfix<br />
query = Select maildir from mailbox,alias_domain where alias_domain.alias_domain = '%d' and mailbox.username = '%u' || '@' || alias_domain.target_domain and mailbox.active = true and alias_domain.active<br />
EOF<br />
<br />
cat - <<EOF >sql/pgsql_virtual_alias_domain_maps.cf<br />
user=postfix<br />
password = $PGPW<br />
hosts = localhost<br />
dbname = postfix<br />
query = select goto from alias,alias_domain where alias_domain.alias_domain='%d' and alias.address = '%u' || '@' || alias_domain.target_domain and alias.active= true and alias_domain.active= true<br />
EOF<br />
<br />
cat - <<EOF >sql/pgsql_virtual_alias_maps.cf<br />
user=postfix<br />
password = $PGPW<br />
hosts = localhost<br />
dbname = postfix<br />
query = Select goto From alias Where address='%s' and active ='1'<br />
EOF<br />
<br />
cat - <<EOF >sql/pgsql_virtual_domains_maps.cf<br />
user=postfix<br />
password = $PGPW<br />
hosts = localhost<br />
dbname = postfix<br />
query = Select domain from domain where domain='%s' and active='1'<br />
EOF<br />
<br />
cat - <<EOF >sql/pgsql_virtual_mailbox_maps.cf<br />
user=postfix<br />
password = $PGPW<br />
hosts = localhost<br />
dbname = postfix<br />
query = Select maildir from mailbox where username='%s' and active=true<br />
EOF<br />
<br />
chown -R postfix:postfix sql<br />
chmod 640 sql/*<br />
<br />
At this point you should be able to start up postfix:<br />
<br />
newaliases # so postfix is happy...<br />
/etc/init.d/postfix start<br />
rc-update add postfix<br />
<br />
=== Create a domain in PostfixAdmin and test ===<br />
<br />
Go to http://host.example.com/postfixadmin/<br />
<br />
Log in using the superadmin account, create a domain for the local box (e.g. example.com), and create a user mailbox (e.g. root).<br />
<br />
From the machine, send a test message:<br />
<br />
sendmail -t root@example.com<br />
subject: test<br />
.<br />
^d<br />
<br />
In /var/log/mail.log (or /var/log/messages, if you still have busybox syslogd running) you should see the message queued. The message should be in /var/mail/domains/example.com/root/new<br />
<br />
== Install Dovecot ==<br />
<br />
Dovecot is the POP3/IMAP server to retrieve mail.<br />
<br />
Install dovecot: <br />
<br />
apk add dovecot dovecot-pgsql<br />
<br />
Edit /etc/dovecot/dovecot.conf:<br />
<br />
<pre><br />
auth_mechanisms = plain login<br />
auth_username_format = %Lu<br />
#auth_verbose = yes<br />
#auth_debug = yes<br />
#auth_debug_passwords = no<br />
<br />
disable_plaintext_auth = no<br />
<br />
mail_location = maildir:/var/mail/domains/%d/%n<br />
<br />
first_valid_gid = 105<br />
first_valid_uid = 102<br />
last_valid_gid = 105<br />
last_valid_uid = 102<br />
<br />
log_timestamp = "%Y-%m-%d %H:%M:%S "<br />
login_greeting = IMAP server ready<br />
<br />
protocols = imap<br />
<br />
service anvil {<br />
client_limit = 2100<br />
}<br />
<br />
ssl_cert = </etc/lighttpd/server-bundle.pem<br />
ssl_key = </etc/lighttpd/server-bundle.pem<br />
<br />
userdb {<br />
args = uid=102 gid=105 home=/var/mail/domains/%d/%n<br />
driver = static<br />
}<br />
<br />
passdb {<br />
args = /etc/dovecot/dovecot-sql.conf<br />
driver = sql<br />
}<br />
<br />
namespace inbox {<br />
inbox = yes<br />
<br />
mailbox Trash {<br />
auto = create<br />
special_use = \Trash<br />
}<br />
<br />
mailbox Spam {<br />
auto = no<br />
special_use = \Junk<br />
}<br />
<br />
mailbox Ham {<br />
auto = no<br />
}<br />
mailbox Sent {<br />
auto = subscribe<br />
special_use = \Sent<br />
}<br />
<br />
}<br />
</pre><br />
<br />
Be sure to replace the uid and gid with the appropriate values for the vmail user.<br />
<br />
We need a certificate for SSL/TLS authentication, so in the example above, we use the lighttpd cert. That way when the cert is renewed/replaced, Dovecot will have access to the new cert as well. <br />
<br />
Create the /etc/dovecot/dovecot-sql.conf file:<br />
<br />
driver = pgsql<br />
connect = host=localhost dbname=postfix user=postfix password=********<br />
password_query = select username,password from mailbox where local_part = '%n' and domain = '%d'<br />
default_pass_scheme = SHA512-CRYPT<br />
<br />
Again, change the password above to your postfix user password, and protect the file from prying eyes:<br />
<br />
chown root:root /etc/dovecot/dovecot-sql.conf<br />
chmod 600 /etc/dovecot/dovecot-sql.conf<br />
<br />
Start dovecot<br />
/etc/init.d/dovecot start<br />
rc-update add dovecot<br />
<br />
== Testing ==<br />
<br />
Make sure your firewall allows in ports 25(SMTP) 110 (POP3), 995 (POP3S), 143(IMAP), 993(IMAPS), or whatever subset you support. <br />
<br />
At this point, you should be able to:<br />
* Create a new domain and add users with PostfixAdmin<br />
* Send mail to those users via SMTP to port 25<br />
* Retrieve mail using the user's full email and password (e.g. username: user@example.com password: ChangeMe)<br />
<br />
== Value Add Features ==<br />
<br />
If you followed the guide above, you now have a functional mail server with many interconnected parts. The features below assume that the server is already running as described above. You should be able to add any or all of these features below to further enhance the mail service.<br />
<br />
=== Virus Scanning ===<br />
<br />
This procedure uses clamav and the postfix content_filter mechanism to scan inbound and outbound email for viruses. Infected emails are dropped. Clean emails are tagged with a "scanned by clamav" header.<br />
<br />
* Install clamav and clamsmtp:<br />
apk add acf-clamav clamsmtp<br />
* Edit the /etc/clamav/clamd.conf file if desired (not necessary in most cases)<br />
* Edit /etc/clamsmtpd.conf and verify the following lines<br />
OutAddress: 10026<br />
Listen: 127.0.0.1:10025 <br />
Header: X-Virus-Scanned: ClamAV using ClamSMTP<br />
Action: drop<br />
User: clamav <br />
* Start the daemons<br />
rc-update add clamd<br />
rc-update add clamsmtpd<br />
/etc/init.d/clamd start<br />
/etc/init.d/clamsmtpd start<br />
* Verify clamsmtp is listening on port 10025:<br />
netstat -anp | grep clamsmtp<br />
* [http://memberwebs.com/stef/software/clamsmtp/postfix.html Following the clamsmtp instructions]<br />
** edit /etc/postfix/main.cf and add:<br />
content_filter = scan:[127.0.0.1]:10025 <br />
** edit /etc/postfix/master.cf and add<br />
# AV scan filter (used by content_filter)<br />
scan unix - - n - 16 smtp<br />
-o smtp_send_xforward_command=yes<br />
-o smtp_enforce_tls=no<br />
# For injecting mail back into postfix from the filter<br />
127.0.0.1:10026 inet n - n - 16 smtpd<br />
-o content_filter=<br />
-o receive_override_options=no_unknown_recipient_checks,no_header_body_checks<br />
-o smtpd_helo_restrictions=<br />
-o smtpd_client_restrictions=<br />
-o smtpd_sender_restrictions=<br />
-o smtpd_recipient_restrictions=permit_mynetworks,reject<br />
-o mynetworks_style=host<br />
-o smtpd_authorized_xforward_hosts=127.0.0.0/8<br />
* postfix reload<br />
* Send and email into a local virtual domain - it should have the ''X-Virus-Scanned: ClamAV using ClamSMTP'' header.<br />
<br />
=== Relay for Authenticated Users ===<br />
<br />
As configured above, the mail server accepts email from the Internet, but it does not relay email. If it is a perimeter exchanger for a protected network, then you can add the protected networks to the ''mynetworks'' configuration line in /etc/postfix/main.cf<br />
<br />
This configuration change allows ''remote'' users to authenticate against the mail server and relay through it. The rules for relaying are:<br />
* Only authenticated users can relay<br />
* Authentication Credentials must be encrypted with TLS or SSL<br />
* Allow Submission and SMTPS ports for relaying (many consumer networks block port 25 - SMTP by default)<br />
The process uses the dovecot authentication mechanism (used with IMAPS) to authenticate users before they are allowed to relay through postfix.<br />
<br />
* Edit /etc/dovecot/dovecot.conf and add the following:<br />
# this is for postfix SASL (authenticated users can relay through us)<br />
<br />
service auth {<br />
unix_listener /var/spool/postfix/private/auth {<br />
group = postfix<br />
mode = 0660<br />
user = postfix<br />
}<br />
unix_listener /var/spool/postfix/auth-master {<br />
group = postfix<br />
mode = 0660<br />
user = vmail<br />
}<br />
user = root<br />
}<br />
<br />
* Restart dovecot<br />
/etc/init.d/dovecot restart<br />
* Edit /etc/postfix/main.cf and add:<br />
# TLS Stuff -- since we allow SASL with tls *only*, we have to set up TLS first <br />
<br />
smtpd_tls_cert_file = /etc/lighttpd/server-bundle.pem<br />
smtpd_tls_key_file = /etc/lighttpd/server-bundle.pem<br />
smtpd_tls_CAfile = /etc/lighttpd/ca-crt.pem<br />
# If tls_security_level is set to "encrypt", then SMTP rejects <br />
# unencrypted email (e.g. normal mail) which is bad.<br />
# By setting it to "may" you get TLS encrypted mail from google, slashdot, and other <br />
# interesting places. Check your logs to see who<br />
smtpd_tls_security_level = may<br />
# Log info about the negotiated encryption levels<br />
smtpd_tls_received_header = yes<br />
smtpd_tls_loglevel = 1<br />
<br />
# SASL - this allows senders to authenticiate themselves<br />
# This along with "permit_sasl_authenticated" in smtpd_recipient_restrictions allows relaying<br />
smtpd_sasl_type = dovecot<br />
smtpd_sasl_path = private/auth<br />
smtpd_sasl_auth_enable = yes<br />
smtpd_sasl_authenticated_header = yes<br />
broken_sasl_auth_clients = yes<br />
smtpd_tls_auth_only = yes<br />
* Edit /etc/postfix/master.cf and enable the submission and smtps transports. They are probably already at the top of your master.cf file, just commented out:<br />
submission inet n - n - - smtpd<br />
-o smtpd_tls_security_level=encrypt<br />
-o smtpd_sasl_auth_enable=yes<br />
-o smtpd_client_restrictions=permit_sasl_authenticated,reject<br />
-o milter_macro_daemon_name=ORIGINATING<br />
smtps inet n - n - - smtpd<br />
-o smtpd_tls_security_level=encrypt<br />
-o smtpd_tls_wrappermode=yes<br />
-o smtpd_sasl_auth_enable=yes<br />
-o smtpd_client_restrictions=permit_sasl_authenticated,reject<br />
-o milter_macro_daemon_name=ORIGINATING<br />
*Verfiy submission and smtps are defined in /etc/services<br />
grep "submission\|ssmtp" /etc/services<br />
submission 587/tcp # mail message submission<br />
submission 587/udp<br />
smtps 465/tcp ssmtp # smtp protocol over TLS/SSL<br />
smtps 465/udp ssmtp<br />
* Restart postfix<br />
postfix reload<br />
<br />
At this point, you should be able to set up a mail client to relay through the server with TLS (port 587) or SSL (port 465) Note that "plain" authentication is used because the underlying link is encrypted. For example, in Thunderbird leave "secure authentication" unchecked, and choose STARTTLS (or TLS) for the connection security.<br />
<br />
=== Mailbox Quotas ===<br />
<br />
In the default configuration, PostfixAdmin knows about quotas, but they are not enforced. Documentation on the web mentions the [http://vda.sourceforge.net vda patch to postfix] to enforce quotas. The only bad thing... its a ''patch''. Postfix and Dovecot are both conservative systems, so if the patch isn't in the upstream source, we'll assume there's a good reason. There is a way of using quotas without patches - and it involves using dovecot's [http://wiki2.dovecot.org/LDA deliver] lda for local delivery.<br />
<br />
* Replace /etc/dovecot/dovecot.conf with the following:<br />
<br />
<pre><br />
auth_mechanisms = plain login<br />
auth_username_format = %Lu<br />
#auth_verbose = yes<br />
#auth_debug = yes<br />
#auth_debug_passwords = no<br />
<br />
disable_plaintext_auth = no<br />
<br />
info_log_path = /var/log/dovecot-info.log<br />
log_path = /var/log/dovecot.log<br />
<br />
mail_location = maildir:/var/mail/domains/%d/%n<br />
<br />
first_valid_gid = 1000<br />
first_valid_uid = 1000<br />
last_valid_gid = 65535<br />
last_valid_uid = 65535<br />
<br />
log_timestamp = "%Y-%m-%d %H:%M:%S "<br />
login_greeting = IMAP server ready<br />
<br />
protocols = imap<br />
<br />
service anvil {<br />
client_limit = 2100<br />
}<br />
<br />
service auth {<br />
unix_listener /var/spool/postfix/auth-master {<br />
group = postfix<br />
mode = 0660<br />
user = vmail<br />
}<br />
unix_listener /var/spool/postfix/private/auth {<br />
group = postfix<br />
mode = 0660<br />
user = postfix<br />
}<br />
user = root<br />
}<br />
<br />
service imap-login {<br />
inet_listener imap {<br />
address = 127.0.0.1<br />
port = 143<br />
}<br />
inet_listener imaps {<br />
address = *<br />
port = 993<br />
}<br />
process_limit = 1024<br />
}<br />
<br />
service pop3-login {<br />
process_limit = 1024<br />
}<br />
<br />
service dict {<br />
unix_listener dict {<br />
group =<br />
mode = 0600<br />
user = vmail<br />
}<br />
}<br />
<br />
ssl_ca = </etc/ssl/certs/<CA Certificate file><br />
ssl_cert = </etc/ssl/private/<Public part of certificate file><br />
ssl_key = </etc/ssl/private/<Private part of certificate file><br />
<br />
passdb {<br />
args = /etc/dovecot/dovecot-pgsql.conf<br />
driver = sql<br />
}<br />
<br />
userdb {<br />
driver = prefetch<br />
}<br />
<br />
userdb {<br />
args = /etc/dovecot/dovecot-pgsql.conf<br />
driver = sql<br />
}<br />
<br />
plugin {<br />
quota = dict:user::proxy::quotadict<br />
<br />
autocreate = Trash<br />
autocreate2 = Spam<br />
autocreate3 = Sent<br />
autosubscribe = Trash<br />
autosubscribe2 = Spam<br />
autosubscribe3 = Sent<br />
}<br />
<br />
protocol imap {<br />
mail_plugins = autocreate quota imap_quota<br />
}<br />
<br />
protocol pop3 { <br />
mail_plugins = quota <br />
} <br />
<br />
dict {<br />
quotadict = pgsql:/etc/dovecot/dovecot-dict-quota.conf<br />
}<br />
<br />
protocol lda {<br />
auth_socket_path = /var/spool/postfix/auth-master<br />
mail_plugins = quota<br />
postmaster_address = postmaster@host.example.com<br />
sendmail_path = /usr/sbin/sendmail<br />
}<br />
</pre><br />
<br />
* edit <tt>/etc/dovecot/dovecot-sql.conf</tt> and replace the user and password queries with the following (you may not have a user_query yet - add it):<br />
<br />
password_query = select username as user, password, 1006 as userdb_uid, 1006 as userdb_gid, '*:bytes=' || quota as userdb_quota_rule from mailbox where local_part = '%n' and domain = '%d'<br />
user_query = select '/var/mail/domains/' || maildir as home, 1006 as uid, 1006 as gid, '*:bytes=' || quota as quota_rule from mailbox where local_part = '%n' and domain ='%d'<br />
<br />
* create <tt>/etc/dovecot/dovecot-dict-quota.conf</tt><br />
connect = host=localhost dbname=postfix user=postfix password=********<br />
<br />
map {<br />
pattern = priv/quota/storage<br />
table = quota2<br />
username_field =username<br />
value_field = bytes<br />
}<br />
<br />
map {<br />
pattern= priv/quota/messages<br />
table = quota2<br />
username_field = username<br />
value_field = messages<br />
}<br />
<br />
Again, change the password above to your postfix user password, and protect the file from prying eyes:<br />
chown dovecot:root /etc/dovecot/dovecot-sql.conf<br />
chmod 600 /etc/dovecot/dovecot-sql.conf<br />
chown dovecot:root /etc/dovecot/dovecot-dict-quota.conf<br />
chmod 600 /etc/dovecot/dovecot-dict-quota.conf<br />
<br />
Side note: [http://wiki2.dovecot.org/Quota/Dict The Dovecot Quota Documentation] mentions the need for a trigger with pgsql. This was created in the PostfixAdmin install, which is why you instantiated the pgsql language when creating the database. If not, you will need to create the trigger, to reference the quota2 table, not the quota table mentioned in the dovecot docs.<br />
<br />
<br />
* create a new transport for the dovecot lda. Add the following to /etc/postfix/master.cf:<br />
# The dovecot deliver lda<br />
dovecot unix - n n - - pipe<br />
flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${user}@${nexthop}<br />
<br />
* Edit the /etc/postfix/main.cf. Replace <br />
virtual_transport = virtual <br />
with<br />
virtual_transport = dovecot<br />
dovecot_destination_recipient_limit = 1<br />
<br />
Change permissions on the /var/log/dovecot* log files, so that the vmail user can write to them:<br />
<br />
chown vmail:vmail /var/log/dovecot*<br />
<br />
Restart Postfix and Dovecot:<br />
<br />
/etc/init.d/postfix restart<br />
/etc/init.d/dovecot restart<br />
<br />
'''TODO''' This will cause over-quota emails to bounce. Which could be a source of backscatter. We need a way of checking quota limits after RBL checking but before the message is accepted in the queue.<br />
<br />
=== WebMail (RoundCube) ===<br />
<br />
[http://roundcube.net/ RoundCube] is an "ajax /Web2.0" web-mail client. These instructions are for the Alpine Linux 2.2 repository <br />
<br />
* Verify that you have at least the following in /etc/postfix/main.cf. Unless you have followed the Relay for Authenticated Users section above, set '''smtpd_tls_auth_only = no''', otherwise leave it set to '''yes''':<br />
<br />
<pre><br />
# SASL - this allows senders to authenticiate themselves<br />
# This along with "permit_sasl_authenticated" in smtpd_recipient_restrictions allows relaying<br />
smtpd_sasl_type = dovecot<br />
smtpd_sasl_path = private/auth<br />
smtpd_sasl_auth_enable = yes<br />
smtpd_sasl_authenticated_header = yes<br />
# Set the next line to no if TLS auth is not configured <br />
smtpd_tls_auth_only = no<br />
</pre><br />
<br />
* Ensure you have followed section ''Relay_for_Authenticated_Users''.<br />
<br />
* Restart the relevant services:<br />
<br />
<pre><br />
/etc/init.d/postfix restart<br />
/etc/init.d/dovecot restart<br />
</pre><br />
<br />
* Add the package and related php modules:<br />
<br />
apk add roundcubemail php-xml php-openssl php-mcrypt php-gd php-iconv php-dom php-intl php-pdo php-ldap php-pdo_pgsql php-zlib<br />
<br />
* Link the roundcube application back into the docroot<br />
<br />
ln -s /usr/share/webapps/roundcube /var/www/domains/host.example.com/www/roundcube<br />
<br />
* Install ''roundcubemail-install'' package<br />
<br />
apk add roundcubemail-installer<br />
<br />
* Follow the instructions in /usr/share/webapps/roundcube/INSTALL:<br />
cd /usr/share/webapps/roundcube<br />
chown -R lighttpd:lighttpd /var/log/roundcube<br />
<br />
su postgres<br />
createuser roundcube<br />
Shall the new role be a superuser? (y/n) n<br />
Shall the new role be allowed to create databases? (y/n) n<br />
Shall the new role be allowed to create more new roles? (y/n) y<br />
createdb -O roundcube -E UNICODE -T template0 roundcubemail<br />
psql roundcubemail<br />
roundcubemail=# ALTER USER roundcube WITH PASSWORD 'the_new_password';<br />
roundcubemail=# \c - roundcube<br />
roundcubemail=> \i /usr/share/webapps/roundcube/SQL/postgres.initial.sql<br />
roundcubemail=> \q<br />
exit<br />
<br />
* Edit /etc/php/php.ini and set date.timezone to your local timezone, or to UTC<br />
<br />
* Restart lighttpd to verify the new php libraries are used<br />
<br />
/etc/init.d/lighttpd restart<br />
<br />
* Get the additional php modules needed:<br />
apk add curl php-phar git<br />
cd /usr/share/webapps/roundcube<br />
curl -sS https://getcomposer.org/installer | php<br />
cp composer.json-dist composer.json<br />
# Note - As of 11 Aug 2015, with Roundcube 1.1.2, there is a regression that is <br />
# fixed here: https://github.com/roundcube/roundcubemail/commit/b3e9764c311a39012de1fa8ffd0fe874fbb322ef<br />
# Update your composer.json accordingly:<br />
# - "pear/mail_mime": ">=1.9.0",<br />
# - "pear/net_smtp": "dev-master"<br />
# + "pear-pear.php.net/mail_mime": ">=1.9.0",<br />
# + "pear-pear.php.net/net_smtp": ">=1.6.3"<br />
php composer.phar install --no-dev <br />
<br />
* Point your browser to https://host.example.com/roundcube/installer<br />
* Start installation<br />
<br />
For the specific configuration parameters in the install step:<br />
<br />
{| class="wikitable"<br />
!Property<br />
!Setting<br />
|-<br />
| ''enable_spellcheck'' || disabled <br />
|-<br />
| ''identities_level'' || one identity with possibility to edit all params but not email address <br />
|-<br />
| ''log driver'' || syslog <br />
|-<br />
| ''sylog_id'' || roundcube <br />
|-<br />
| ''syslog_facility'' || mailsubsystem <br />
|-<br />
| ''db_dnsw'' || pgsql properties, as described above <br />
|-<br />
| ''imap_host'' || 127.0.0.1 <br />
|-<br />
| ''default port'' || 143<br />
|-<br />
| ''auto_create_user'' || enabled <br />
|-<br />
| ''smtp_server'' || 127.0.0.1<br />
|-<br />
| ''smtp_port'' || 25<br />
|-<br />
| ''smtp_user/smtp_pass'' || enable ''Use Current IMAP username and password for SMTP authentication''<br />
|-<br />
| ''smtp_log'' || enable (optional, but gives additional log record)<br />
|}<br />
<br />
The other items can be left at default settings, or adjusted if desired.<br />
<br />
* Follow the instructions in step 2 of the install to copy the files to the server<br />
* You should now be able to get to roundcube at https://host.example.com/roundcube<br />
<br />
* After its working, the INSTALL file recommends removing the install directory.<br />
<br />
apk del roundcubemail-installer<br />
<br />
* Disable installer mode in /etc/roundcube/main.inc.php file:<br />
<br />
$rcmail_config['enable_installer'] = false;<br />
<br />
* Change the ownership and permissions<br />
<br />
cd /usr/share/webapps/roundcube<br />
chown -R root:root LICENSE UPGRADING INSTALL README CHANGELOG<br />
chmod -R 600 LICENSE UPGRADING INSTALL README CHANGELOG <br />
<br />
* If needed customize logos such as '''watermark.gif''', '''roundcube_logo.gif''', '''favicon.ico'''<br />
<br />
* If you would like to disable displaying of standard logos update template files accordingly<br />
<br />
* Comment all entries like '''<div ... img src="/images/roundcube_logo.png"...''' in files:<br />
<br />
includes/header.html <br />
templates/error.html<br />
templates/messageprint.html<br />
templates/login.html<br />
templates/printmessage.html<br />
<br />
* Comment all entries like '''<img src="/images/watermark.gif"...''' in files:<br />
<br />
templates/identities.html<br />
templates/messageerror.html<br />
watermark.html<br />
<br />
==== Enable Plug-ins ====<br />
<br />
RoundCube has various useful plug-ins, which could be found in ''/usr/share/webapps/roundcube/plugins'' directory. For example you may want to enable ''password'' plug-in to let users change their passwords directly from RoundCube using an extra Password Tab added to User Settings.<br />
<br />
* Grant limited permissions for ''roundcube'' database role <br />
psql -U postgres postfix<br />
postfix=# GRANT UPDATE (password,modified) ON mailbox TO roundcube;<br />
postfix=# GRANT SELECT (username) ON mailbox TO roundcube;<br />
postfix=# GRANT INSERT ON log TO roundcube;<br />
postfix=# \q<br />
<br />
* Setup ''password'' plug-in parameters in ''/usr/share/webapps/roundcube/plugins/password/config.inc.php''<br />
mv /usr/share/webapps/roundcube/plugins/password/config.inc.php.dist /usr/share/webapps/roundcube/plugins/password/config.inc.php<br />
vi /usr/share/webapps/roundcube/plugins/password/config.inc.php<br />
<br />
<pre><br />
$rcmail_config['password_minimum_length'] = 7;<br />
$rcmail_config['password_require_nonalpha'] = true;<br />
...<br />
$rcmail_config['password_db_dsn'] = 'pgsql://roundcube:<roundcube_password>@localhost/postfix';<br />
...<br />
$rcmail_config['password_query'] = "UPDATE mailbox set password = %c, modified = NOW() where username = %u; INSERT INTO log (timestamp,username,domain,action,data) VALUES (NOW(),%u || ' (' || %h || ')',%d,'edit_password',%u)";<br />
</pre><br />
<br />
* Enable ''password'' plug-in<br />
vi /usr/share/webapps/roundcube/config/main.inc.php<br />
<br />
<pre><br />
...<br />
$rcmail_config['plugins'] = array('password');<br />
</pre><br />
<br />
* Enable ''create_default_folders'' for RoundCube<br />
vi /usr/share/webapps/roundcube/config/main.inc.php<br />
<br />
<pre><br />
...<br />
$rcmail_config['create_default_folders'] = TRUE;<br />
...<br />
</pre><br />
<br />
=== OpenLDAP based Address Book ===<br />
<br />
This OpenLDAP configuration uses the SQL backend, which represents information stored in PostgreSQL as an LDAP subtree for Address Book functionality for email lookups, user authentication or even replication account information between sites. This procedure uses some metainformation to translate LDAP queries to SQL queries, leaving relational schema untouched, which allows SQL and LDAP applications to inter-operate without replication, and exchange data as needed. The SQL backend uses UnixODBC to connect to PostgresSQL. <br />
<br />
* Install OpenLDAP and ODBC<br />
<br />
<pre><br />
apk add openldap libldap openldap-back-sql php-ldap unixodbc psqlodbc ca-certificates<br />
</pre><br />
<br />
* Update "postfix" database (it will add 'id' columns to mailbox and domain tables, also will create tables and views to represent LDAP metainformation)<br />
<br />
'''Note''': These instructions are for example domain example.com. So make sure you replaced all entries of 'example' and 'com' according to your domain name parts.<br />
<br />
Put the following into a new file called '''script''':<br />
<br />
<pre><br />
ALTER TABLE domain ADD COLUMN id SERIAL; <br />
ALTER TABLE mailbox ADD COLUMN id SERIAL; <br />
<br />
CREATE TABLE ldap_entry_objclasses (<br />
entry_id integer NOT NULL,<br />
oc_name character varying(64)<br />
);<br />
<br />
CREATE TABLE ldap_oc_mappings (<br />
name character varying(64) NOT NULL,<br />
keytbl character varying(64) NOT NULL,<br />
keycol character varying(64) NOT NULL,<br />
create_proc character varying(255),<br />
delete_proc character varying(255),<br />
expect_return integer NOT NULL<br />
);<br />
<br />
ALTER TABLE ldap_oc_mappings ADD COLUMN id SERIAL;<br />
ALTER TABLE ldap_oc_mappings ADD PRIMARY KEY (id);<br />
<br />
CREATE TABLE ldap_attr_mappings (<br />
oc_map_id integer NOT NULL REFERENCES ldap_oc_mappings(id),<br />
name character varying(255) NOT NULL,<br />
sel_expr character varying(255) NOT NULL,<br />
sel_expr_u character varying(255),<br />
from_tbls character varying(255) NOT NULL,<br />
join_where character varying(255),<br />
add_proc character varying(255),<br />
delete_proc character varying(255),<br />
param_order integer NOT NULL,<br />
expect_return integer NOT NULL<br />
);<br />
<br />
ALTER TABLE ldap_attr_mappings ADD COLUMN id SERIAL;<br />
ALTER TABLE ldap_attr_mappings ADD PRIMARY KEY (id);<br />
<br />
CREATE VIEW ldap_dcs AS<br />
((SELECT (domain.id + 100000) AS id,<br />
('dc='::text || replace((domain.domain)::text, '.'::text, ',dc='::text)) AS dn,<br />
1 AS oc_map_id,<br />
100000 AS parent,<br />
0 AS keyval,<br />
domain.domain<br />
FROM domain<br />
WHERE domain.domain <> 'ALL')<br />
UNION<br />
(SELECT 100000 AS id,<br />
('dc=' || regexp_replace((domain.domain)::text, '.*\\.', ''::text)) AS dn,<br />
1 AS oc_map_id,<br />
0 AS parent,<br />
0 AS keyval,<br />
(regexp_replace((domain.domain)::text, '.*\\.', ''::text)) AS domain<br />
FROM domain<br />
WHERE domain.domain <> 'ALL'<br />
LIMIT 1));<br />
<br />
CREATE VIEW ldap_entries AS<br />
SELECT mailbox.id,<br />
((('cn='::text || initcap(replace(split_part((mailbox.username)::text, '@'::text, 1), '.'::text, ' '::text))) || ',dc='::text) ||<br />
replace(regexp_replace((mailbox.username)::text, '.*@', ''::text), '.'::text, ',dc='::text)) AS dn,<br />
1 AS oc_map_id,<br />
(SELECT ldap_dcs.id<br />
FROM ldap_dcs<br />
WHERE ((ldap_dcs.domain)::text = (mailbox.domain)::text)) AS parent,<br />
mailbox.id AS keyval<br />
FROM mailbox<br />
UNION<br />
SELECT ldap_dcs.id,<br />
ldap_dcs.dn,<br />
ldap_dcs.oc_map_id,<br />
ldap_dcs.parent,<br />
ldap_dcs.keyval<br />
FROM ldap_dcs;<br />
</pre><br />
'''''Question to experts: Is this normal to have in this script "WARNING: nonstandard use of \\ in a string literal"?'''''<br />
<br />
Finally, execute the commands in the file with:<br />
cat script | psql -U postfix postfix<br />
rm script<br />
<br />
* Fill out LDAP tables according to following example (make sure to separate values with TABs):<br />
<br />
Put the following into a new file called '''script''':<br />
<br />
<pre><br />
COPY ldap_oc_mappings (id, name, keytbl, keycol, create_proc, delete_proc, expect_return) FROM stdin;<br />
1 exampleBox mailbox id \N \N 1<br />
\.<br />
COPY ldap_attr_mappings (id, oc_map_id, name, sel_expr, sel_expr_u, from_tbls, join_where, add_proc, delete_proc, param_order, expect_return) FROM stdin;<br />
1 1 displayName mailbox.name \N mailbox \N \N \N 3 0<br />
2 1 mail mailbox.username \N mailbox \N \N \N 3 0<br />
3 1 cn mailbox.name \N mailbox \N \N \N 3 0<br />
4 1 userPassword '{CRYPT}'||mailbox.password \N mailbox \N \N \N 3 0<br />
\.<br />
</pre><br />
<br />
Finally, execute the commands in the file with:<br />
cat script | psql -U postfix postfix<br />
rm script<br />
<br />
* Check that "ldap_dcs" view looks something like this:<br />
<br />
<pre><br />
echo 'select * from ldap_dcs' | psql -U postgres postfix<br />
</pre><br />
<br />
<pre><br />
id | dn | oc_map_id | parent | keyval | domain <br />
--------+-----------------------------+-----------+--------+--------+--------------------<br />
100000 | dc=com | 1 | 0 | 0 | com<br />
100001 | dc=example,dc=com | 1 | 100000 | 0 | example.com<br />
</pre><br />
<br />
* Check that "ldap_entries" view looks something like this:<br />
<br />
<pre><br />
echo 'select * from ldap_entries' | psql -U postgres postfix<br />
</pre><br />
<br />
<pre><br />
id | dn | oc_map_id | parent | keyval <br />
--------+-------------------------------------------------------+-----------+--------+--------<br />
1 | cn=address1,dc=example,dc=com | 1 | 100001 | 1<br />
...<br />
123 | cn=address123,dc=example,dc=com | 1 | 100001 | 1<br />
100000 | dc=com | 1 | 0 | 0<br />
100001 | dc=example,dc=com | 1 | 100000 | 0<br />
</pre><br />
<br />
* Configure ODBC parameters<br />
<br />
Edit /etc/odbc.ini:<br />
<br />
<pre><br />
[PostgreSQL]<br />
Description = Connection to Postgres<br />
Driver = PostgreSQL<br />
Trace = Yes<br />
TraceFile = sql.log<br />
Database = postfix<br />
Servername = 127.0.0.1<br />
UserName =<br />
Password =<br />
Port = 5432<br />
Protocol = 6.4<br />
ReadOnly = No<br />
RowVersining = No<br />
ShowSystemTables = No<br />
ShowOidColumn = No<br />
FakeOidIndex = No<br />
ConnSettings =<br />
</pre><br />
<br />
Edit /etc/odbcinst.ini:<br />
<br />
<pre><br />
[PostgreSQL]<br />
Description = PostgreSQL driver for Linux<br />
Driver = /usr/lib/psqlodbcw.so<br />
Setup = /usr/lib/libodbcpsqlS.so<br />
FileUsage = 1<br />
</pre><br />
<br />
* Test ODBC connection<br />
<br />
<pre><br />
echo "select * from domain;" | isql PostgreSQL postgres<br />
</pre><br />
<br />
* Provide permission to certificate for LDAP server<br />
<br />
<pre><br />
chown ldap /etc/lighttpd/server-bundle.pem<br />
</pre><br />
<br />
* Edit LDAP schema<br />
<br />
Edit /etc/openldap/schema/example.com.schema:<br />
<br />
<pre><br />
attributetype ( 0.9.2342.19200300.100.1.3<br />
NAME ( 'mail' 'rfc822Mailbox' )<br />
DESC 'RFC1274: RFC822 Mailbox'<br />
EQUALITY caseIgnoreIA5Match<br />
SUBSTR caseIgnoreIA5SubstringsMatch<br />
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )<br />
<br />
attributetype ( 2.16.840.1.113730.3.1.241<br />
NAME 'displayName'<br />
DESC 'RFC2798: preferred name to be used when displaying entries'<br />
EQUALITY caseIgnoreMatch<br />
SUBSTR caseIgnoreSubstringsMatch<br />
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15<br />
SINGLE-VALUE )<br />
<br />
objectclass ( 2.16.840.1.113730.3.2.2<br />
NAME 'exampleBox'<br />
DESC 'example.com mailbox'<br />
MUST ( displayName $ mail $ userPassword )<br />
)<br />
<br />
# RFC 1274 + RFC 2247<br />
attributetype ( 0.9.2342.19200300.100.1.25<br />
NAME ( 'dc' 'domainComponent' )<br />
DESC 'RFC1274/2247: domain component'<br />
EQUALITY caseIgnoreIA5Match<br />
SUBSTR caseIgnoreIA5SubstringsMatch<br />
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )<br />
<br />
attributetype ( 2.5.4.46 NAME 'dnQualifier'<br />
DESC 'RFC2256: DN qualifier'<br />
EQUALITY caseIgnoreMatch<br />
ORDERING caseIgnoreOrderingMatch<br />
SUBSTR caseIgnoreSubstringsMatch<br />
SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 )<br />
</pre><br />
<br />
* Configure LDAP server<br />
<br />
Edit /etc/openldap/slapd.conf:<br />
<br />
<pre><br />
include /etc/openldap/schema/example.com.schema<br />
pidfile /var/run/openldap/slapd.pid<br />
argsfile /var/run/openldap/slapd.args<br />
<br />
# Uncomment next five TLS... lines if you want to use LDAPs (secured). Probably you don't want it...<br />
#TLSCipherSuite HIGH<br />
#TLSCACertificateFile /etc/lighttpd/ca-crt.pem<br />
#TLSCertificateFile /etc/lighttpd/server-bundle.pem<br />
#TLSCertificateKeyFile /etc/lighttpd/server-bundle.pem<br />
#TLSVerifyClient never <br />
<br />
# This is needed for proper representation of MD5-CRYPT format stored in database<br />
# see more details in http://strugglers.net/~andy/blog/2010/01/23/openldap-and-md5crypt/<br />
password-hash {CRYPT}<br />
password-crypt-salt-format "$1$%.8s"<br />
<br />
loglevel stats<br />
moduleload /usr/lib/openldap/back_sql.so<br />
sizelimit 3000<br />
<br />
database sql<br />
<br />
dbname PostgreSQL<br />
dbuser postfix<br />
dbpasswd *****<br />
<br />
suffix "dc=example,dc=com"<br />
<br />
upper_func "upper"<br />
strcast_func "text"<br />
concat_pattern "?||?"<br />
has_ldapinfo_dn_ru no<br />
lastmod off<br />
<br />
access to attrs=userPassword by * auth<br />
<br />
access to * by peername.ip=127.0.0.1 read<br />
# by peername.ip=<IP>%<netmask> read<br />
# by peername.ip=<IP> read<br />
by users read<br />
</pre><br />
<br />
* Set permissions for slapd.conf<br />
<br />
<pre><br />
chown ldap:ldap /etc/openldap/slapd.conf<br />
</pre><br />
<br />
* Configure startup parameters to make sure that LDAP server start AFTER PostgreSQL and listens on localhost with clear text and public IP with SSL. In case you uncommented TLS lines in slapd.conf use this string: OPTS="-h 'ldaps:// ldap://'"<br />
<br />
Edit /etc/conf.d/slapd:<br />
<br />
<pre><br />
rc_need="postgresql" <br />
OPTS="-h 'ldap://'"<br />
</pre><br />
<br />
* Start LDAP server<br />
<br />
<pre><br />
rc-update add slapd default<br />
/etc/init.d/slapd start<br />
</pre><br />
<br />
* Configure LDAP client utilities. In case you uncommented TLS lines in slapd.conf replace ldap with ldaps<br />
<br />
Edit /etc/openldap/ldap.conf<br />
<br />
<pre><br />
BASE dc=example,dc=com<br />
URI ldap://host.example.com<br />
<br />
# Uncomment next three TLS... lines if you want to use LDAPs (secured). Probably you don't want it...<br />
#TLS_CACERT /etc/lighttpd/ca-crt.pem<br />
#TLS_CERT /etc/lighttpd/server-bundle.pem<br />
#TLS_KEY /etc/lighttpd/server-bundle.pem<br />
</pre><br />
<br />
* Test LDAP server<br />
<br />
<pre><br />
ldapsearch -z 3<br />
ldapsearch -z 3 -x -W -D cn=admin,dc=example,dc=com<br />
ldapsearch -z 3 -x -W -D cn=address1,dc=example,dc=com<br />
</pre><br />
<br />
* Configure RoundCube webmail for email lookups<br />
<br />
In order to enable php-ldap support you need to restart lighttpd server<br />
<br />
/etc/init.d/lighttpd restart<br />
<br />
Edit /etc/roundcube/main.inc.php:<br />
<br />
<pre><br />
$rcmail_config['ldap_debug'] = false;<br />
...<br />
$rcmail_config['address_book_type'] = 'sql';<br />
<br />
$rcmail_config['ldap_public']['example.com'] = array(<br />
'name' => 'example.com',<br />
'hosts' => array('127.0.0.1'),<br />
'port' => 389,<br />
'use_tls' => false,<br />
'user_specific' => false,<br />
'base_dn' => 'dc=example,dc=com',<br />
'bind_dn' => '',<br />
'bind_pass' => '',<br />
'writable' => false,<br />
'LDAP_Object_Classes' => array("top", "exampleBox"),<br />
'required_fields' => array("cn", "sn", "mail"),<br />
'LDAP_rdn' => 'mail',<br />
'ldap_version' => 3,<br />
'search_fields' => array('mail', 'cn', 'sn', 'givenName'),<br />
'name_field' => 'cn',<br />
'email_field' => 'mail',<br />
'surname_field' => 'sn',<br />
'firstname_field' => 'gn',<br />
'sort' => 'cn',<br />
'scope' => 'sub',<br />
'filter' => '(objectClass=*)', // Construct here any filter you need<br />
'fuzzy_search' => true);<br />
<br />
$rcmail_config['autocomplete_addressbooks'] = array('sql','example.com');<br />
</pre><br />
<br />
* Fix PostfixAdmin to work with the new table definition<br />
<br />
Edit /var/www/domains/example.com/www/postfixadmin/list-domain.php. Replace the line:<br />
<pre><br />
SELECT domain.* , COUNT( DISTINCT mailbox.username ) AS mailbox_count<br />
</pre><br />
With the lines:<br />
<pre><br />
SELECT domain.domain, domain.description, domain.aliases, domain.mailboxes,<br />
domain.maxquota, domain.quota, domain.transport, domain.backupmx, domain.created,<br />
domain.modified, domain.active, COUNT( DISTINCT mailbox.username ) AS mailbox_count<br />
</pre><br />
<br />
== log rotation ==<br />
<br />
Ensure the busybox cron service is started and is configured to auto-start:<br />
<br />
/etc/init.d/cron start<br />
rc-update add cron default<br />
<br />
Add log rotate:<br />
<br />
apk add logrotate<br />
<br />
Edit ''/etc/logrotate.conf'' as desired, but the defaults should be sufficient for most people.<br />
<br />
== Optional: Configure Web Server Virtual Domains ==<br />
<br />
'''Note:''' These steps can be done ''in addition to'' the default lighttpd configuration above, which allows you to access the ACF, PostfixAdmin and Roundcube interfaces as subfolders of one web service.<br />
<br />
'''Note:''' If you provide SSL access for multiple domain site you may need to follow http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs:SSL#SSL-on-multiple-domains in order to provide multi-domain certificates. If you would like to redirect hosts to their secure equivalents use the following instructions http://redmine.lighttpd.net/projects/lighttpd/wiki/HowToRedirectHttpToHttps.<br />
<br />
This server hosts three separate web applications, and these can be handled as three ''different'' virtual domains on the same web server. They will be distinguished by their DNS names, so you can choose domains for the three separate services (or at least the ones you want to publish):<br />
<br />
* ACF - Alpine Configuration Framework for managing the server<br />
* PostfixAdmin - for managing the postfix installation<br />
* RoundCube - for accessing individual mailboxes<br />
<br />
Choose three different domains (from here on known as ACF_DOMAIN, POSTFIXADMIN_DOMAIN, and ROUNDCUBE_DOMAIN) and configure DNS for all three to point to the IP address of your host. These should be DNS '''A''' records.<br />
<br />
Then, configure lighttpd to handle the three separate domains by editing /etc/lighttpd/lighttpd.conf:<br />
<br />
<pre><br />
$HTTP["host"] == "ACF_DOMAIN" {<br />
simple-vhost.server-root = "/var/www/domains/"<br />
simple-vhost.default-host = "/ACF_DOMAIN/"<br />
simple-vhost.document-root = "www/"<br />
}<br />
<br />
$HTTP["host"] == "POSTFIXADMIN_DOMAIN" {<br />
simple-vhost.server-root = "/var/www/domains/"<br />
simple-vhost.default-host = "/POSTFIXADMIN_DOMAIN/"<br />
simple-vhost.document-root = "www/"<br />
}<br />
<br />
$HTTP["host"] == "ROUNDCUBE_DOMAIN" {<br />
simple-vhost.server-root = "/var/www/domains/"<br />
simple-vhost.default-host = "/ROUNDCUBE_DOMAIN/"<br />
simple-vhost.document-root = "www/"<br />
}<br />
</pre><br />
<br />
And, then link the appropriate www directories.<br />
<pre><br />
mkdir -p /var/www/domains/ACF_DOMAIN<br />
ln -s /usr/share/acf/www /var/www/domains/ACF_DOMAIN/www<br />
<br />
mkdir -p /var/www/domains/POSTFIXADMIN_DOMAIN<br />
ln -s /var/www/domains/host.example.com/www/postfixadmin /var/www/domains/POSTFIXADMIN_DOMAIN/www<br />
<br />
mkdir -p /var/www/domains/ROUNDCUBE_DOMAIN<br />
ln -s /usr/share/webapps/roundcube /var/www/domains/ROUNDCUBE_DOMAIN/www<br />
</pre><br />
<br />
== Optional: Enable compression in Lighttpd ==<br />
<br />
* Uncomment ''mod_compress'' and ''mod_setenv'' and modify website section as follows<br />
<br />
mkdir -p /var/lib/lighttpd/cache<br />
chown lighttpd:lighttpd /var/lib/lighttpd/cache<br />
<br />
vi /etc/lighttpd/lighttpd.conf<br />
<br />
...<br />
"mod_setenv",<br />
"mod_compress",<br />
...<br />
$HTTP["host"] == "ROUNDCUBE_DOMAIN" {<br />
...<br />
static-file.etags = "enable"<br />
etag.use-mtime = "enable"<br />
$HTTP["url"] =~ "^/(plugins|skins|program)" { setenv.add-response-header = ( "Cache-Control" => "public, max-age=2592000") }<br />
compress.cache-dir = var.statedir + "/cache/compress"<br />
compress.filetype = ("text/plain", "text/html", "text/javascript", "text/css", "text/xml", "image/gif", "image/png")<br />
}<br />
<br />
[[Category:Mail]]<br />
[[Category:PHP]]<br />
[[Category:SQL]]<br />
[[Category:ACF]]</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Alpine_package_format&diff=8290Alpine package format2012-06-29T21:03:19Z<p>Aalatchm: correction: filenames in data.tar.gz should not start with leading "."</p>
<hr />
<div>{{Draft}}<br />
<br />
From apk-tools-2.0_pre15 there is support for signing of packages and indexes. This introduced a new format for both packages and indexes. This document describes the new format.<br />
<br />
The new apk package are 2 combined tar.gz packages, control.tar.gz and data.tar.gz. The final .apk package is created by concatenating control.tar.gz and data.tar.gz.<br />
<br />
For example:<br />
{{Cmd|cat $controldir/control.tar.gz $controldir/data.tar.gz > mypackage-1.0-r0.apk}}<br />
<br />
== control.tar.gz ==<br />
The control package contains<br />
* .PKGINFO<br />
* .pre-install/upgrade/deinstall (optional)<br />
* .post-install/upgrade/deinstall (optional)<br />
<br />
Since the data.tar.gz will follow the after the control.tar.gz, the end-of-tar record in the tar archive must be removed. This is done by filtering the tar package through ''abuild-tar --cut'':<br />
<br />
<pre>tar -c .PKGNIFO .pre-install | abuild-tar --cut | gzip -9 > $controldir/control.tar.gz</pre><br />
<br />
=== .PKGINFO ===<br />
the .PKGINFO is very similar to archlinux's .PKGINFO. <br />
<br />
Format is ''key''[space]=[space]''value''.<br />
key = value<br />
<br />
The following ''keys'' are supported:<br />
* pkgname - the name of package<br />
* pkgver - the version, including the pkgrel.<br />
* depends (each dependency has its own line)<br />
* datahash<br />
<br />
=== .*-install/upgrade/deinstall ===<br />
The .pre-install, .pre-upgrade, .pre-deinstall scripts are executed before respectively, install, upgrade or uninstallation of a package. Apk will halt current action if script exits with error.<br />
<br />
The .post-* scripts are executed after respecitvely install, upgade or uninstall of a package.<br />
<br />
== data.tar.gz ==<br />
The data is a tar package with checksums embedded in the tar headers. The tar headers with checksuma are created by filtering the tar archive via the ''abuild-tar'' utility.<br />
<br />
The data.tar.gz can be created with:<br />
<br />
cd $pkgdir<br />
tar -c * | abuild-tar --hash | gzip -9 > $controldir/data.tar.gz<br />
<br />
The reason for creating data.tar.gz separately is because a hash will be created and stored in .PKGINFO for future package signing.<br />
<br />
[[Category:Development]] [[Category:Package Manager]]</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Tutorials_and_Howtos&diff=5789Tutorials and Howtos2011-10-11T14:23:23Z<p>Aalatchm: /* Misc */ added link</p>
<hr />
<div>[[Image:package_edutainment.svg|left|link=]]<br />
{{TOC right}}'''Welcome to Tutorials and Howtos, a place of basic and advanced configuration tasks for your Alpine Linux.'''<br />
The tutorials are hands-on and the reader is expected to try and achieve the goals described in each step, possibly with the help of a good examples. The output in one step is the starting point for the following step.<br/><br />
Howtos are smaller articles explaining how to perform a particular task with Alpine Linux. We encourage people to send in both complete articles as well as requesting topics to be covered. If you think you have the skills and knowledge to write an Alpine Linux related article please do so on this Wiki. If you want to request a topic, please add your request in this page [[Talk:Tutorials_and_Howtos|Discussion]]. <br />
<br />
=System=<br />
==Initial setup==<br />
* [[Setting up a basic vserver]]<br />
* [[Alpine Linux package management#Local_Cache | How to enable APK caching]]<br />
* [[Enable Serial Console on Boot]]<br />
* [[Upgrading to Edge]]<br />
==Storage==<br />
* [[Setting up Logical Volumes with LVM]]<br />
* [[Setting up a software raid1 array]]<br />
* [[iSCSI Target and Initiator Configuration]]<br />
* [[iSCSI Raid and Clustered File Systems]]<br />
* [[High performance SCST iSCSI Target on Linux software Raid]]<br />
==Networking==<br />
* [[Configure Networking]]<br />
* [[Howto Configure a Network Bridge]]<br />
* [[Howto Configure static routes]]<br />
* [[Using serial modem]]<br />
* [[Using HSDPA modem]]<br />
* [[Setting up Satellite Internet Connection]]<br />
* [[Connecting to a wireless accesspoint]]<br />
* [[Using Alpine on Windows domain with IPSEC isolation]]<br />
==Desktop Environment==<br />
* [[XFCE Setup]]<br />
* [[Gnome Setup]]<br />
==Misc==<br />
* [[Manually editing a existing apkovl]]<br />
* [[Changing passwords for ACF]]<br />
* [[Formatting HD/Floppy/Other]]<br />
* [[Back Up a Flash Memory Installation]]<br />
<br />
=Applications=<br />
==Networking==<br />
* [[Setting up a OpenVPN-server with Alpine]]<br />
* [[Setting up a ssh-server]]<br />
* [[Generating SSL certs with ACF]]<br />
* [[Setting up traffic monitoring using rrdtool (and snmp)]]<br />
* [[Setting up unbound DNS server]]<br />
* [[Setting up nsd DNS server]]<br />
<br />
==VoIP==<br />
* [[Setting up Zaptel/Asterisk on Alpine]]<br />
* [[Freepbx on Alpine Linux]]<br />
==Web==<br />
* [[Setting Up Lighttpd With FastCGI]]<br />
* [[Apache authentication: NTLM Single Signon]]<br />
===Webapps===<br />
* [[2600hz]] ''FreeSWITCH, Asterisk GUI web acces tool.''<br />
* [[Awstats]] ''Free log file analyzer.''<br />
* [[Setting up Cacti|Cacti]]<br />
* [[Drupal]] ''Content Management System (CMS) written in PHP.''<br />
* [[EyeOS]] ''Cloud Computing Desktop.''<br />
* [[FreePBX_V3]] ''FreeSWITCH, Asterisk GUI web acces tool.''<br />
* [[Glpi]] ''Information Resource-Manager.''<br />
* [[MediaWiki]] ''Free web-based wiki software application''<br />
* [[Setting Up Fprobe And Ntop|Ntop]] ''NetFlow collection and analysis using a remote fprobe instance''<br />
* [[Pastebin]] ''Pastebin software application''<br />
* [[Phpizabi]] ''Social Networking Platform.''<br />
* [[PhpPgAdmin]] ''Web-based administration tool for PostgreSQL.''<br />
* [[Phpmyadmin]] ''Web-based administration tool for MYSQL.''<br />
* [[Redmine]] ''Project management system ''<br />
* [[Request-Tracker]] ''Ticket system''<br />
* [[Roundcube]] ''Webmail system''<br />
* [[Setting up Smokeping|Smokeping]] ''Network latency monitoring''<br />
* [[Statusnet]] ''Microblogging Platform.''<br />
* [[Sqstat]] ''Script to look active squid users connections.''<br />
* [[Webmin]] ''A web-based interface for Linux system.''<br />
* [[WordPress]] ''Web software to create website or blog. ''<br />
* [[Setting up Zabbix|Zabbix]]<br />
==Mail==<br />
* [[Hosting services on Alpine]] ''(This applies to hosting mail, webservices and other services)''<br />
** [[Setting up postfix with virtual domains]]<br />
** [[Protecting your email server with Alpine]]<br />
** [[Hosting Web/Email services on Alpine]]<br />
==Misc==<br />
* [[Multiple Instances of Services]]<br />
* [[Setting up Transmission (bittorrent) with Clutch WebUI]]<br />
* [[Freeradius Active Directory Integration]]<br />
* [[Traffic monitoring]] ''(For Alpine Linux firewalls)''<br />
* [[Setting up NRPE daemon]] ''(Performs remote Nagios checks)''<br />
* [[Setting up lm_sensors]]<br />
* [[Screen on console]]<br />
* [[Using espeak on Alpine Linux]]<br />
* [[IPTV How To]]<br />
* [[Pllua]]<br />
* [[Error message on boot: Address space collision: host bridge window conflicts with Adaptor ROM]]<br />
=Complete Solutions=<br />
* [[Replacing non-Alpine Linux with Alpine remotely]]<br />
* [[Fault Tolerant Routing with Alpine Linux]]<br />
* [[ISP Mail Server HowTo]] ''(Postfix+PostfixAdmin+DoveCot+Roundcube+ClamAV+Spamd - A full-serivce ISP mail server)''<br />
** [[ISP Mail Server Upgrade 2.x]]<br />
** [[ISP Mail Server 2.x HowTo]] ''(Beta, please test)''<br />
* [[High Availability High Performance Web Cache]] ''uCarp + HAProxy for High Availability Services such as Squid web proxy''<br />
= Drafts =<br />
Currently unfinished docs.<br />
* [[Install Alpine on coLinux]]<br />
* [[Using Racoon for Remote Sites]]<br />
* [[Setting up Transparent Squid Proxy]] ''(Covers Squid proxy and URL Filtering system)''<br />
** [[Obtaining user information via SNMP]] ''(Using the Squark Squid authentication helper)''<br />
* [[Setting up Streaming an Asterisk Channel]]<br />
* [[Setting up A Network Monitoring and Inventory System]] ''((Nagios + OpenAudit and related components)''<br />
* [[Intrusion Detection using Snort]] ''Installing and configuring Snort and related applications on Alpine 2.0.x''<br />
* [[IP Accounting]] ''Installing and configuring pmacct for IP Accounting, Netflow/sFlow collector''<br />
* [[Howto Setup a Wireless Access Point]] ''Setting up Secure Wireless AP w/ WPA encryption with bridge to wired network''<br />
* [[Xen Dom0]] ''Setting up Alpine as a dom0 for Xen hypervisor''<br />
<br />
= Obsolete Docs =<br />
Those are candidates for rewriting/removal.<br />
* [[Bootstrapping Alpine on Soekris net4xxx]]<br />
* [[Bootstrapping Alpine on PC Engines ALIX.3]]<br />
* [[Installing XUbuntu using Alpine boot floppy]]<br />
* [[Setting up trac wiki]]</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Back_Up_a_Flash_Memory_Installation&diff=5788Back Up a Flash Memory Installation2011-10-11T14:22:26Z<p>Aalatchm: Created page with "If you have installed Alpine Linux on flash memory, such as a CF card or USB stick, you may wish to create a backup. This procedure may also be used to migrate an Alpine Linux ..."</p>
<hr />
<div>If you have installed Alpine Linux on flash memory, such as a CF card or USB stick, you may wish to create a backup. <br />
<br />
This procedure may also be used to migrate an Alpine Linux installation from one form of flash media to another.<br />
<br />
== Install Alpine Linux on the backup medium ==<br />
<br />
Follow the instructions at [[Installing Alpine on USB]] to install Alpine Linux on the backup medium (CF/USB). Install the same version of Alpine Linux as you have on the running system (you can determine this using the command "cat /etc/alpine-release").<br />
<br />
<br />
== Copy over the cache directory ==<br />
<br />
If you have [[Alpine Linux package management#Local_Cache |enabled APK caching]] for packages that are downloaded over the Internet, then you should copy over the "cache" directory from the running system to your backup medium.<br />
<br />
For example, if the backup medium is labeled "sdb" (use the command "dmesg" to see what name your recently inserted device has recieved), and the system is booted from USB, you would run:<br />
<br />
* {{Cmd|mount -t vfat /dev/sdb1 /mnt}}<br />
* {{Cmd|cp -a /media/usbdisk/cache /mnt/}}<br />
* {{Cmd|umount /mnt}}<br />
<br />
== Copy over the configuration overlay file (apkovl) ==<br />
<br />
All the custom configuration of your system is stored in a file named HOSTNAME.apkovl.tar.gz, where HOSTNAME is the locally configured hostname of the system (see the file /etc/hostname).<br />
<br />
Simply copy this file to the root of your backup medium.<br />
<br />
For example, if the backup medium is labeled "sdb" (use the command "dmesg" to see what name your recently inserted device has recieved), and the system is booted from USB, you would run:<br />
<br />
* {{Cmd|mount -t vfat /dev/sdb1 /mnt}}<br />
* {{Cmd|cp -a /media/usbdisk/*.apkovl.tar.gz /mnt/}}<br />
* {{Cmd|umount /mnt}}</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Template:Copying_Alpine_to_Flash&diff=5777Template:Copying Alpine to Flash2011-10-10T15:33:59Z<p>Aalatchm: /* Copy Alpine to a {{{1|Flash Medium}}} */</p>
<hr />
<div>== Copy Alpine to a {{{1|Flash Medium}}} ==<br />
# Boot the computer from the Alpine Linux CD-ROM<br />
# Insert the removable {{{1|flash medium (CF or USB stick)}}} into the computer.<br />
# Determine the name your computer uses for your {{{1|flash medium}}}. The following step is one way to do this.<br />
#* After inserting the {{{1|flash medium}}}, run the command:<br />
#* {{Cmd|dmesg}}<br />
#* At the end of this command you should see the name of your {{{1|flash medium}}}, likely starting with "sd". (For example: "sda").<br />
#* The remainder of this document will assume that your {{{1|flash medium}}} is called /dev/sda<br />
<br />
{{Warning|Be very careful about this. You do not want to mistakenly wipe your hard drive if it's on /dev/sda}}<br />
<br />
=== Format {{{1|Flash Medium}}} ===<br />
{{Cmd|fdisk /dev/sda}}<br />
* '''p''' Print list of partitions<br />
* '''d''' Delete all partitions (this may take a few steps)<br />
* '''n''' Create a new partition<br />
* '''p''' A primary partition<br />
* '''1''' Partition number 1<br />
** Use defaults for first and last cylinder (just press [Enter] twice).<br />
* '''t''' Change partition type<br />
* '''c''' Type: Win95 FAT32 (LBA)<br />
* '''a''' <big>Make the partition bootable (set boot flag)</big><br />
* '''1''' Partition number 1<br />
* '''w''' Write your changes to the device<br />
<br />
=== Install Syslinux ===<br />
{{Note|If the following commands fail due to 'No such file or directory', you may have to remove and reinsert the CF card, or even reboot, to get /dev/sda1 to appear}}<br />
# Install syslinux and dosfstools. If you have booted from an Alpine CD-ROM, use these commands:<br />
#* {{Cmd|apk add syslinux dosfstools}}<br />
#* {{Cmd|{{{|dd if=/usr/share/syslinux/mbr.bin of=/dev/sda}}}}}<br />
# Format the {{{1|flash medium}}} with a VFAT filesystem:<br />
#* {{Cmd|mkdosfs -F32 /dev/sda1}}<br />
#* {{Cmd|syslinux /dev/sda1}}<br />
#* {{Cmd|mkdir -p /media/sda1}}<br />
#* {{Cmd|mount -t vfat /dev/sda1 /media/sda1}}<br />
#Copy the files to the {{{1|flash medium}}}<br />
#* {{Cmd|cd /media/cdrom}}<br />
#* {{Cmd|cp -a .alpine-release * /media/sda1/ }}<br />
<br />
== Troubleshooting ==<br />
When your USB device is formatted to other filesystem than fat32, you might have to specify the necessary filesystem modules in boot parameters.<br />
<br />
To do so, mount the device, and alter the syslinux.cfg file line from <br />
append initrd=/boot/grsec.gz alpine_dev=usbdisk:vfat modules=loop,cramfs,sd-mod,usb-storage quiet<br />
to<br />
append initrd=/boot/grsec.gz alpine_dev=usbdisk:vfat modules=loop,cramfs,sd-mod,usb-storage,ext3 quiet<br />
<br />
in case of using ext3 formatted partition. Similar procedure might apply to other filesystems (if they are supported by syslinux or other bootloader of your choice and alpine kernel).<br />
<br />
Also, specifying waitusb=X option might help with certain usb devices that take a bit longer to register. X stands for the amount of seconds kernel will wait before looking for the installation media.</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Upgrading_Alpine_-_v1.9.x&diff=5776Upgrading Alpine - v1.9.x2011-10-10T13:08:33Z<p>Aalatchm: clarify how to upgrade packages after CD or USB kernel upgrade.</p>
<hr />
<div>This document covers upgrading for Alpine Linux version 1.9 and later. Thanks to many improvements in Alpine Linux 1.9 and later, it is possible to easily upgrade in most scenarios.<br />
<br />
All examples/instructions/actions mentioned in this document should be executed on the box that you are planning to upgrade (unless you are instructed otherwise).<br />
<br />
== Upgrading an Alpine Linux Hard-disk installation ==<br />
<br />
When Alpine Linux is installed to hard drive, upgrading the installation is simple.<br />
<br />
{{Using_Internet_Repositories_for_apk-tools}}<br />
<br />
Ensure you have the latest available version of the Alpine Linux Package Manager first before upgrading anything else:<br />
{{Cmd|apk add -u apk-tools}}<br />
<br />
=== Upgrading to Alpine Linux 2.2 and later from 2.1 ===<br />
Since '''apk''' tool has been significantly changed first make sure you have upgraded ''apk-tools'' package to latest version available in 2.1 repositories:<br />
<br />
{{Cmd|apk update --update-cache<br />
apk add --upgrade apk-tools}}<br />
<br />
Change repositories:<br />
{{Cmd|vi /etc/apk/repositories}}<br />
<br />
http://nl.alpinelinux.org/alpine/v2.2/main<br />
# or any other mirror <br />
<br />
Proceed with update and upgrade:<br />
{{Cmd|apk update --update-cache<br />
apk upgrade --available --update-cache}}<br />
<br />
Reboot the system to load new kernel<br />
{{Cmd|sync<br />
reboot}}<br />
<br />
=== Upgrading to Alpine Linux 2.2 and later from 2.0 or 1.10.x ===<br />
Since '''apk''' tool has been significantly changed you need to download and install manually the latest version of ''apk-tools'' package.<br />
<br />
If current version is 1.10.x remove GNU Wget before attempting an upgrade:<br />
{{Cmd|apk del wget}}<br />
<br />
Download latest apk-tools package and install it:<br />
{{Cmd|wget http://nl.alpinelinux.org/alpine/v2.2/main/x86/apk-tools-2.1.0_rc1-r2.apk<br />
apk add apk-tools-2.1.0_rc1-r2.apk --update-cache}}<br />
<br />
Change repositories:<br />
{{Cmd|vi /etc/apk/repositories}}<br />
<br />
http://nl.alpinelinux.org/alpine/v2.2/main<br />
# or any other mirror <br />
<br />
Proceed with update and upgrade:<br />
{{Cmd|apk update --update-cache<br />
apk upgrade --available --update-cache}}<br />
<br />
Reboot the system to load new kernel<br />
{{Cmd|sync<br />
reboot}}<br />
<br />
=== Upgrading to Alpine Linux 2.0 or 2.1 from earlier versions ===<br />
For upgrading to Alpine Linux 2.0 or 2.1 from earlier versions, the following steps apply.<br />
<br />
Remove GNU Wget before attempting an upgrade:<br />
{{Cmd|apk del wget}}<br />
<br />
Upgrade all remaining packages, including the kernel. The --available switch is used to force all packages to be upgraded, even if they have the same version number, due to changes in uClibc:<br />
{{Cmd|apk upgrade --update-cache --available<br />
sync}}<br />
<br />
=== All Other Upgrades ===<br />
Upgrade all remaining packages, including the kernel if applicable:<br />
{{Cmd|apk upgrade<br />
sync}}<br />
<br />
{{Note|You will need to restart any services that have been upgraded to begin using the upgraded versions. If the kernel is upgraded, you will need to reboot to begin using the upgraded version.}}<br />
<br />
== Upgrading Alpine Linux on CD ==<br />
<br />
You may have an installation where the boot media being used (such as a CD, for example) is separate from the media used to store the configuration information. In this case, simply download the latest ISO, and replace the boot media contents with the contents of the latest ISO. If you are booting from a CD, this would simply mean replacing the CD with a CD made from the new image and rebooting the Alpine Linux box. <br />
<br />
=== Update remaining packages from Web repository ===<br />
<br />
If you are using [[How_to_enable_APK_caching|APK caching]] you should also perform the following steps:<br />
<br />
{{Using_Internet_Repositories_for_apk-tools}}<br />
<br />
Ensure you have the latest available version of the Alpine Linux Package Manager first before upgrading anything else:<br />
{{Cmd|apk add -u apk-tools}}<br />
<br />
{{Cmd|apk upgrade<br />
sync}}<br />
<br />
== Upgrading Alpine Linux on Flash Memory (such as CF/USB) ==<br />
<br />
Your installation may consist of Alpine Linux running on Compact Flash or USB media. In most cases, it should be sufficient to upgrade most packages using the '''Alpine Linux Hard-disk Installation''' upgrade procedures described above. However, for new packages to survive after a reboot, you should enable [[How_to_enable_APK_caching|APK caching]].<br />
<br />
{{Warning|As the newer version of alpine may include kernel upgrades, simply pointing the Alpine Linux Package Manager to an Internet-based repository and running ''apk upgrade'' will not be enough, as kernel components are not upgraded when Alpine Linux is run from memory.}}<br />
<br />
{{Upgrading_Alpine_environmentvars}}<br />
<br />
=== Upgrade Operating System ===<br />
<br />
Start by checking that you have enough space on your media.<BR><br />
You need at least 400MB available space.<br />
{{Cmd|df -h | grep "Filesystem\|$LBU_MEDIA"}}<br />
<br />
==== Download and verify new release ====<br />
<br />
{{Tip|If using Alpine Linux 2.2.3 or newer, use the following command to download, mount and copy files as needed for you: {{Cmd|setup-bootable -u {{#latestalp:alpine|url}} /media/$LBU_MEDIA}}. Once the command completes, proceed to the [[#Update remaining packages from Web repository|Update remaining packages from Web repository]] section. }} <br />
<br />
Start downloading a new '.iso' and a '.sha1' file <br />
{{Cmd|cd /media/$LBU_MEDIA<br />
wget -c {{#latestalp:alpine|url}}<br />
wget {{#latestalp:alpine|url}}.sha1}}<br />
<br />
Check integrity of the downloaded files ''(it might take some time)''<br />
{{Cmd|sha1sum -c {{#latestalp:alpine|file}}.sha1}}<br />
''The output of the above command should say 'OK'.<BR>''<br />
''If says 'FAILED', delete the iso file and download it again.''<br />
<br />
==== Copy the new release ====<br />
{{Note|There is a tool, ''setup-bootable'', in alpine-1.10.4 and newer, that does the mounting and copying for you. With this tool simply do: {{Cmd|setup-bootable -u {{#latestalp:alpine|file}} /media/$LBU_MEDIA}}. Once the command completes, proceed to the [[#Update remaining packages from Web repository|Update remaining packages from Web repository]] section.<br />
}}<br />
<br />
Mount the ISO.<br />
<br />
{{Cmd|mount -t iso9660 {{#latestalp:alpine|file}} /mnt}}<br />
<br />
Back up files that you have modified. For example, you might have modified ''syslinux.cfg'' to show console output on a serial port.<BR><br />
<br />
{{Cmd|cp /media/$LBU_MEDIA/syslinux.cfg /media/$LBU_MEDIA/syslinux.cfg.my}}<br />
<br />
Install the '''rsync''' package if necessary, and copy the files:<br />
<br />
{{Cmd|cd /mnt<br />
apk add rsync<br />
rsync --delete -rltv .alpine-release * /media/$LBU_MEDIA/}}<br />
<br />
Restore your backed up files ''(in case you had any)''<br />
<br />
{{Cmd|mv -f /media/$LBU_MEDIA/syslinux.cfg.my /media/$LBU_MEDIA/syslinux.cfg}}<br />
<br />
Make sure that all files are permanently saved in right place <br />
<br />
{{Cmd|sync}}<br />
<br />
==== Clean up ====<br />
Clean up the downloaded/unpacked files<br />
{{Cmd|cd ..<br />
umount /mnt<br />
rm /media/$LBU_MEDIA/{{#latestalp:alpine|file}}<br />
rm /media/$LBU_MEDIA/{{#latestalp:alpine|file}}.sha1}}<br />
<br />
=== Save changes ===<br />
Now that all upgrades are done, we should save our settings to our media (which you hopefully have backed up prior to doing this upgrade).<br />
{{Cmd|lbu ci}}<br />
<br />
=== Load new kernel ===<br />
In most cases you will need to reboot Alpine Linux (especially if there are changes in the kernel):<br />
{{Cmd|reboot}}<br />
{{Note|If you know what you are doing, you might not need to reboot. But make sure that all services affected by the upgrade are restarted.}}<br />
<br />
=== Update remaining packages from Web repository ===<br />
If you are using [[How_to_enable_APK_caching|APK caching]] you should perform the following steps:<br />
<br />
{{Using_Internet_Repositories_for_apk-tools}}<br />
<br />
Ensure you have the latest available version of the Alpine Linux Package Manager first before upgrading anything else:<br />
{{Cmd|apk add -u apk-tools}}<br />
{{Cmd|apk upgrade<br />
sync}}</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Redmine&diff=5082Redmine2011-04-07T13:31:50Z<p>Aalatchm: add mysql to lbu</p>
<hr />
<div>Install Lighttpd with FastCGI<br />
{{:Setting Up Lighttpd With FastCGI}}<br />
<br />
Install extra packages for redmine:<br />
apk add fcgi mysql mysql-dev rubygems fcgi-dev sqlite-dev<br />
<br />
Install the following rubygems (gem install <gemname> --version <version>). Note: newer versions of the gems may work, but these have been confirmed working in Alpine 2.1.2:<br />
gem install -V --no-rdoc --no-ri actionmailer --version 2.3.3<br />
gem install -V --no-rdoc --no-ri activerecord --version 2.3.3<br />
gem install -V --no-rdoc --no-ri activeresource --version 2.3.3 <br />
gem install -V --no-rdoc --no-ri edavis10-object_daddy --version 0.4.3<br />
gem install -V --no-rdoc --no-ri fcgi --version 0.8.8<br />
gem install -V --no-rdoc --no-ri mocha --version 0.9.10<br />
gem install -V --no-rdoc --no-ri mysql --version 2.8.1<br />
gem install -V --no-rdoc --no-ri rails --version 2.3.3<br />
gem install -V --no-rdoc --no-ri shoulda --version 2.10.3<br />
gem install -V --no-rdoc --no-ri sqlite3 --version 1.3.3<br />
<br />
Configure MySql<br />
<br />
/usr/bin/mysql_install_db --user=mysql<br />
/etc/init.d/mysql start && rc-update add mysql default<br />
/usr/bin/mysqladmin -u root password 'password'<br />
<br />
Create the redmine database<br />
<br />
mysql -u root -p<br />
<br />
create database redmine character set utf8;<br />
grant all privileges on redmine.* to 'redmine'@'localhost' identified by 'Secur3P@ass';<br />
flush privileges;<br />
exit<br />
<br />
Create redmine folder<br />
<br />
mkdir -p /usr/share/webapps/redmine<br />
<br />
Download, unpack and move Redmine<br />
<br />
cd /tmp/<br />
wget http://rubyforge.org/frs/download.php/73140/redmine-1.0.3.tar.gz<br />
tar zxvf redmine-1.0.3.tar.gz<br />
mv redmine-1.0.3/* /usr/share/webapps/redmine/<br />
<br />
Change permissions<br />
<br />
chown -R lighttpd:lighttpd /usr/share/webapps/redmine<br />
chmod 0666 /usr/share/webapps/log/production.log<br />
mkdir /var/run/redmine<br />
chown lighttpd:lighttpd /var/run/redmine<br />
<br />
Edit the database config file and add the mysql password at every occurrence of "password:"<br />
<br />
cp /usr/share/webapps/redmine/config/database.yml.example /usr/share/webapps/redmine/config/database.yml<br />
nano /usr/share/webapps/redmine/config/database.yml <br />
<br />
Some more steps<br />
<br />
cd /usr/share/webapps/redmine<br />
mv public/dispatch.fcgi.example public/dispatch.fcgi<br />
<br />
rake generate_session_store<br />
RAILS_ENV=production rake db:migrate<br />
RAILS_ENV=production rake redmine:load_default_data <br />
<br />
Note: keep default language of '''en'''<br />
<br />
Start the Redmine testing webserver<br />
<br />
ruby /usr/share/webapps/redmine/script/server webrick -e production<br />
<br />
Now you can browse to '''localhost:3000''' an log using '''admin''' user and '''admin''' password.<br />
<br />
Once Redmine is confirmed working, kill webrick.<br />
<br />
Set up lighttpd by editing lighttpd.conf.<br />
: Uncomment the following line:<br />
"mod_alias",<br />
: Add the following content to the end of the file:<br />
$HTTP["url"] =~ "^/redmine/" {<br />
alias.url = ("/redmine" => "/usr/share/webapps/redmine/public")<br />
server.document-root = "/usr/share/webapps/redmine/public/"<br />
server.error-handler-404 = "/redmine/dispatch.fcgi"<br />
index-file.names = ("dispatch.fcgi")<br />
# Change *-procs to 2 if you need to use Upload Progress or other tasks that<br />
# *need* to execute a second request while the first is still pending.<br />
fastcgi.server += (<br />
".fcgi" => (<br />
"localhost" => (<br />
"min-procs" => 1,<br />
"max-procs" => 2,<br />
"check-local" => "disable",<br />
"socket" => "/var/run/redmine/fcgi.socket",<br />
"bin-path" => "/usr/bin/ruby /usr/share/webapps/redmine/public/dispatch.fcgi",<br />
"bin-environment" => (<br />
"RAILS_ENV" => "production"<br />
)<br />
)<br />
)<br />
)<br />
}<br />
<br />
Configure a relative URL by editing /usr/share/webapps/redmine/config/environment.rb: Add the line shown below, within the code block "Rails::Initializer.run do |config|"<br />
config.action_controller.relative_url_root = '/redmine'<br />
<br />
Restart lighttpd<br />
/etc/init.d/lighttpd restart<br />
<br />
Note: To enable email to ticket creation from unknown users/email addresses (after allowing anonymous issue creation within Redmine UI) for the 'myproject' project in Redmine:<br />
<br />
#!/usr/bin/perl<br />
# Author: Jeff Bilyk<br />
# March 2, 2011<br />
#Script to take email from stdin, then:<br />
# - Check redmine database to see if the user exists<br />
# - If user doesn't exist, create the user<br />
# - Pass the email on the redmine utility:<br />
# - echo "email contents" | rake redmine:email:read RAILS_ENV="production" project=myproject<br />
<br />
use strict;<br />
use DBI;<br />
# global variables<br />
my $DbName = 'redmine';<br />
my $DbUser = 'redmine';<br />
my $DbPassword = 'Secur3P@ass';<br />
my @fields;<br />
my @address;<br />
my $existinguser;<br />
<br />
# Get email from stdin<br />
my @email = <STDIN>;<br />
<br />
# Parse field for "for"<br />
foreach (@email)<br />
{<br />
if ($_ =~ /From/)<br />
{<br />
@fields = (split /</,$_);<br />
@address = (split />/,$fields[1]);<br />
}<br />
}<br />
<br />
my $dbh = DBI->connect('dbi:mysql:' . $DbName, $DbUser, $DbPassword, { PrintError => 0 }) or die "SQL Connect Error:" . DBI->errstr;<br />
<br />
# Find out if there're any existing users with the specified email address<br />
my $sqlStatement = "SELECT * from users where mail = '$address[0]';";<br />
<br />
my $sqlCommand = $dbh->prepare($sqlStatement);<br />
<br />
$sqlCommand->execute or die "SQL Error: " . DBI->errstr;<br />
<br />
my @sqlRecordset;<br />
$existinguser = 'maybe';<br />
<br />
@sqlRecordset = $sqlCommand->fetchrow_array;<br />
<br />
if ($sqlRecordset[0] == '') {<br />
printf "@sqlRecordset \n";<br />
$existinguser = 'no';<br />
}<br />
else {<br />
$existinguser = 'yes';<br />
}<br />
<br />
# If there isn't a user already, then create one<br />
if ($existinguser == 'no')<br />
{<br />
my @name = (split /@/,$address[0]);<br />
printf "Current variables: $name[0] $address[0] \n";<br />
$sqlStatement = "INSERT INTO users (login, firstname, lastname, mail, mail_notification, admin, status, language, type) values (\"$name[0]\", \"$name[0]\", \" \", \"$address[0]\", 0, 0, 1, \"en\", \"User\");";<br />
$sqlCommand = $dbh->prepare($sqlStatement);<br />
$sqlCommand->execute or die "SQL Error: " .DBI->errstr;<br />
printf "User created";<br />
}<br />
<br />
my $timeinsec = `date +%s`;<br />
open (MYFILE, ">>/var/tmp/$timeinsec");<br />
print MYFILE "@email";<br />
close (MYFILE);<br />
<br />
system("sed -i 's/^ //' /var/tmp/$timeinsec");<br />
system("sed -i 's/^ //' /var/tmp/$timeinsec");<br />
<br />
`cd /usr/share/webapps/redmine && rake redmine:email:read RAILS_ENV="production" project=myproject < /var/tmp/$timeinsec`;<br />
exit 0<br />
<br />
Configure LBU<br />
lbu inc /usr/lib/ruby<br />
lbu inc /usr/share/webapps<br />
lbu inc /var/lib/mysql</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Redmine&diff=5081Redmine2011-04-07T09:58:49Z<p>Aalatchm: corrections using alpine-2.1.6. Edge repository no longer needed. Some missing steps were added.</p>
<hr />
<div>Install Lighttpd with FastCGI<br />
{{:Setting Up Lighttpd With FastCGI}}<br />
<br />
Install extra packages for redmine:<br />
apk add fcgi mysql mysql-dev rubygems fcgi-dev sqlite-dev<br />
<br />
Install the following rubygems (gem install <gemname> --version <version>). Note: newer versions of the gems may work, but these have been confirmed working in Alpine 2.1.2:<br />
gem install -V --no-rdoc --no-ri actionmailer --version 2.3.3<br />
gem install -V --no-rdoc --no-ri activerecord --version 2.3.3<br />
gem install -V --no-rdoc --no-ri activeresource --version 2.3.3 <br />
gem install -V --no-rdoc --no-ri edavis10-object_daddy --version 0.4.3<br />
gem install -V --no-rdoc --no-ri fcgi --version 0.8.8<br />
gem install -V --no-rdoc --no-ri mocha --version 0.9.10<br />
gem install -V --no-rdoc --no-ri mysql --version 2.8.1<br />
gem install -V --no-rdoc --no-ri rails --version 2.3.3<br />
gem install -V --no-rdoc --no-ri shoulda --version 2.10.3<br />
gem install -V --no-rdoc --no-ri sqlite3 --version 1.3.3<br />
<br />
Configure MySql<br />
<br />
/usr/bin/mysql_install_db --user=mysql<br />
/etc/init.d/mysql start && rc-update add mysql default<br />
/usr/bin/mysqladmin -u root password 'password'<br />
<br />
Create the redmine database<br />
<br />
mysql -u root -p<br />
<br />
create database redmine character set utf8;<br />
grant all privileges on redmine.* to 'redmine'@'localhost' identified by 'Secur3P@ass';<br />
flush privileges;<br />
exit<br />
<br />
Create redmine folder<br />
<br />
mkdir -p /usr/share/webapps/redmine<br />
<br />
Download, unpack and move Redmine<br />
<br />
cd /tmp/<br />
wget http://rubyforge.org/frs/download.php/73140/redmine-1.0.3.tar.gz<br />
tar zxvf redmine-1.0.3.tar.gz<br />
mv redmine-1.0.3/* /usr/share/webapps/redmine/<br />
<br />
Change permissions<br />
<br />
chown -R lighttpd:lighttpd /usr/share/webapps/redmine<br />
chmod 0666 /usr/share/webapps/log/production.log<br />
mkdir /var/run/redmine<br />
chown lighttpd:lighttpd /var/run/redmine<br />
<br />
Edit the database config file and add the mysql password at every occurrence of "password:"<br />
<br />
cp /usr/share/webapps/redmine/config/database.yml.example /usr/share/webapps/redmine/config/database.yml<br />
nano /usr/share/webapps/redmine/config/database.yml <br />
<br />
Some more steps<br />
<br />
cd /usr/share/webapps/redmine<br />
mv public/dispatch.fcgi.example public/dispatch.fcgi<br />
<br />
rake generate_session_store<br />
RAILS_ENV=production rake db:migrate<br />
RAILS_ENV=production rake redmine:load_default_data <br />
<br />
Note: keep default language of '''en'''<br />
<br />
Start the Redmine testing webserver<br />
<br />
ruby /usr/share/webapps/redmine/script/server webrick -e production<br />
<br />
Now you can browse to '''localhost:3000''' an log using '''admin''' user and '''admin''' password.<br />
<br />
Once Redmine is confirmed working, kill webrick.<br />
<br />
Set up lighttpd by editing lighttpd.conf.<br />
: Uncomment the following line:<br />
"mod_alias",<br />
: Add the following content to the end of the file:<br />
$HTTP["url"] =~ "^/redmine/" {<br />
alias.url = ("/redmine" => "/usr/share/webapps/redmine/public")<br />
server.document-root = "/usr/share/webapps/redmine/public/"<br />
server.error-handler-404 = "/redmine/dispatch.fcgi"<br />
index-file.names = ("dispatch.fcgi")<br />
# Change *-procs to 2 if you need to use Upload Progress or other tasks that<br />
# *need* to execute a second request while the first is still pending.<br />
fastcgi.server += (<br />
".fcgi" => (<br />
"localhost" => (<br />
"min-procs" => 1,<br />
"max-procs" => 2,<br />
"check-local" => "disable",<br />
"socket" => "/var/run/redmine/fcgi.socket",<br />
"bin-path" => "/usr/bin/ruby /usr/share/webapps/redmine/public/dispatch.fcgi",<br />
"bin-environment" => (<br />
"RAILS_ENV" => "production"<br />
)<br />
)<br />
)<br />
)<br />
}<br />
<br />
Configure a relative URL by editing /usr/share/webapps/redmine/config/environment.rb: Add the line shown below, within the code block "Rails::Initializer.run do |config|"<br />
config.action_controller.relative_url_root = '/redmine'<br />
<br />
Restart lighttpd<br />
/etc/init.d/lighttpd restart<br />
<br />
Note: To enable email to ticket creation from unknown users/email addresses (after allowing anonymous issue creation within Redmine UI) for the 'myproject' project in Redmine:<br />
<br />
#!/usr/bin/perl<br />
# Author: Jeff Bilyk<br />
# March 2, 2011<br />
#Script to take email from stdin, then:<br />
# - Check redmine database to see if the user exists<br />
# - If user doesn't exist, create the user<br />
# - Pass the email on the redmine utility:<br />
# - echo "email contents" | rake redmine:email:read RAILS_ENV="production" project=myproject<br />
<br />
use strict;<br />
use DBI;<br />
# global variables<br />
my $DbName = 'redmine';<br />
my $DbUser = 'redmine';<br />
my $DbPassword = 'Secur3P@ass';<br />
my @fields;<br />
my @address;<br />
my $existinguser;<br />
<br />
# Get email from stdin<br />
my @email = <STDIN>;<br />
<br />
# Parse field for "for"<br />
foreach (@email)<br />
{<br />
if ($_ =~ /From/)<br />
{<br />
@fields = (split /</,$_);<br />
@address = (split />/,$fields[1]);<br />
}<br />
}<br />
<br />
my $dbh = DBI->connect('dbi:mysql:' . $DbName, $DbUser, $DbPassword, { PrintError => 0 }) or die "SQL Connect Error:" . DBI->errstr;<br />
<br />
# Find out if there're any existing users with the specified email address<br />
my $sqlStatement = "SELECT * from users where mail = '$address[0]';";<br />
<br />
my $sqlCommand = $dbh->prepare($sqlStatement);<br />
<br />
$sqlCommand->execute or die "SQL Error: " . DBI->errstr;<br />
<br />
my @sqlRecordset;<br />
$existinguser = 'maybe';<br />
<br />
@sqlRecordset = $sqlCommand->fetchrow_array;<br />
<br />
if ($sqlRecordset[0] == '') {<br />
printf "@sqlRecordset \n";<br />
$existinguser = 'no';<br />
}<br />
else {<br />
$existinguser = 'yes';<br />
}<br />
<br />
# If there isn't a user already, then create one<br />
if ($existinguser == 'no')<br />
{<br />
my @name = (split /@/,$address[0]);<br />
printf "Current variables: $name[0] $address[0] \n";<br />
$sqlStatement = "INSERT INTO users (login, firstname, lastname, mail, mail_notification, admin, status, language, type) values (\"$name[0]\", \"$name[0]\", \" \", \"$address[0]\", 0, 0, 1, \"en\", \"User\");";<br />
$sqlCommand = $dbh->prepare($sqlStatement);<br />
$sqlCommand->execute or die "SQL Error: " .DBI->errstr;<br />
printf "User created";<br />
}<br />
<br />
my $timeinsec = `date +%s`;<br />
open (MYFILE, ">>/var/tmp/$timeinsec");<br />
print MYFILE "@email";<br />
close (MYFILE);<br />
<br />
system("sed -i 's/^ //' /var/tmp/$timeinsec");<br />
system("sed -i 's/^ //' /var/tmp/$timeinsec");<br />
<br />
`cd /usr/share/webapps/redmine && rake redmine:email:read RAILS_ENV="production" project=myproject < /var/tmp/$timeinsec`;<br />
exit 0<br />
<br />
Configure LBU<br />
lbu inc /usr/lib/ruby<br />
lbu inc /usr/share/webapps</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Release_Notes_for_Alpine_2.1.4&diff=4781Release Notes for Alpine 2.1.42011-01-07T11:13:41Z<p>Aalatchm: clarifications</p>
<hr />
<div>We are pleased to announce the Alpine 2.1.4 release.<br />
<br />
This release includes an update to 2.6.35.10-based kernels. Hyper-V fixes have been applied to these kernels.<br />
<br />
Boot scripts have been updated so that if at least one network interface starts successfully, then services that depend on networking will be started. In previous releases (since Alpine 1.9.0) ''all'' network interfaces had to start successfully for this to happen. <br />
<br />
Also, Busybox contains a fix for a long-standing bug that caused crontab files to mysteriously disappear.<br />
<br />
Please consult the [http://redmine.alpinelinux.org/versions/show/26 bugtracker] and [http://git.alpinelinux.org/cgit/aports/log/?h=v2.1.4 cgit] for more details.<br />
<br />
== Package changes since 2.1.3 ==<br />
<pre><br />
Upgraded/downgraded packages (from version):<br />
acf-alpine-conf-0.4.0-r2 (0.4.0-r1)<br />
acf-freeswitch-vmail-0.0.10-r0 (0.0.9-r0)<br />
alpine-base-2.1.4-r0 (2.1.3-r0)<br />
alpine-conf-2.5.4-r1 (2.5.4-r0)<br />
apk-tools-2.0.7-r2 (2.0.7-r0)<br />
busybox-1.17.4-r1 (1.17.3-r3)<br />
dahdi-linux-grsec-2.6.35.10-r0 (2.6.35.9-r2)<br />
iscsitarget-grsec-2.6.35.10-r2 (2.6.35.9-r4)<br />
kamailio-3.1.1-r0 (3.1.0-r1)<br />
libmysqlclient-5.1.51-r2 (5.1.51-r1)<br />
linux-firmware-2.6.35.10-r0 (2.6.35.9-r2)<br />
linux-grsec-2.6.35.10-r0 (2.6.35.9-r2)<br />
mkinitfs-2.1.2-r1 (2.1.2-r0)<br />
openrc-0.6.1-r4 (0.6.1-r2)<br />
xtables-addons-grsec-2.6.35.10-r1 (2.6.35.9-r3)<br />
</pre><br />
<br />
{{UpgradeTo2}}</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Template:UpgradeTo2&diff=4776Template:UpgradeTo22011-01-07T10:58:07Z<p>Aalatchm: /* Important notes when upgrading from v1.10 */</p>
<hr />
<div>== Important notes when upgrading from v1.10 ==<br />
* The v2.0 series introduces an ABI-incompatible version of uClibc with NPTL threading support. This means that you cannot mix packages from older releases with v2.0. To upgrade you will need to make sure that you only have v2.0 repositories in your /etc/apk/repositories list and then do: {{Cmd|apk upgrade --update-cache --available}}<br />
{{Note|There might be packages with same version number in v1.10 repositories so it is very important that the --available option is there to make sure that those gets replaced properly}}<br />
* You must remove GNU wget before doing the upgrade and only use busybox wget.<br />
{{Cmd|apk del wget}}<br />
* All .so links moved to -dev package. It might be an idea to remove alpine-sdk and all *-dev packages before doing the upgrade. If you get problems due to a -dev package want overwrite a .so file owned by other package then you might want use the --force option.<br />
{{Note|Uninstalling alpine-sdk might remove sudo. To make it stay you'll first have to do: {{Cmd|apk add sudo}} }}</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Tutorials_and_Howtos&diff=4766Tutorials and Howtos2011-01-06T17:40:07Z<p>Aalatchm: added pllua</p>
<hr />
<div>[[Image:package_edutainment.svg|left|link=]]<br />
{{TOC right}}'''Welcome to Tutorials and Howtos, a place of basic and advanced configuration tasks for your Alpine Linux.'''<br />
The tutorials are hands-on and the reader is expected to try and achieve the goals described in each step, possibly with the help of a good examples. The output in one step is the starting point for the following step.<br/><br />
Howtos are smaller articles explaining how to perform a particular task with Alpine Linux. We encourage people to send in both complete articles as well as requesting topics to be covered. If you think you have the skills and knowledge to write an Alpine Linux related article please do so on this Wiki. If you want to request a topic, please add your request in this page [[Talk:Tutorials_and_Howtos|Discussion]]. <br />
<br />
== Installation ==<br />
* [[Setting up a basic vserver]]<br />
* [[Setting up Logical Volumes with LVM]]<br />
* [[Replacing non-Alpine Linux with Alpine remotely]]<br />
* [[XFCE Setup]]<br />
* [[Enable Serial Console on Boot]]<br />
* [[How to enable APK caching]]<br />
* [[Install Alpine on VirtualBox]]<br />
* [[Upgrading to Edge]]<br />
* [[Setting up a software raid1 array]]<br />
* [[Running Alpine Linux As a QEMU networked Guest ]]<br />
* [[Manually editing a existing apkovl]]<br />
<br />
== Networking ==<br />
* [[Configure Networking]]<br />
* [[Howto Configure a Network Bridge]]<br />
* [[Using HSDPA modem]]<br />
* [[Using Alpine on Windows domain with IPSEC isolation]]<br />
* [[Setting up Satellite Internet Connection]]<br />
* [[Connecting to a wireless accesspoint]]<br />
<br />
== iSCSI ==<br />
* [[iSCSI Target and Initiator Configuration]]<br />
* [[iSCSI Raid and Clustered File Systems]]<br />
* [[High performance SCST iSCSI Target on Linux software Raid]]<br />
<br />
== Network Services ==<br />
* [[Setting Up Lighttpd With FastCGI]]<br />
* [[Setting up a OpenVPN-server with Alpine]]<br />
* [[Setting up Zaptel/Asterisk on Alpine]]<br />
* [[Setting up Transmission (bittorrent) with Clutch WebUI]]<br />
* [[Hosting services on Alpine]] ''(This applies to hosting mail, webservices and other services)''<br />
** [[Setting up postfix with virtual domains]]<br />
** [[Protecting your email server with Alpine]]<br />
** [[Hosting Web/Email services on Alpine]]<br />
* [[Setting up a ssh-server]]<br />
* [[Multiple Instances of Services]]<br />
* [[ISP Mail Server HowTo]] ''(Postfix+PostfixAdmin+DoveCot+Roundcube+ClamAV+Spamd - A full-serivce ISP mail server)''<br />
* [[Freepbx on Alpine Linux]]<br />
* [[Apache authentication: NTLM Single Signon]]<br />
* [[Generating SSL certs with ACF]]<br />
* [[Changing passwords for ACF]]<br />
* [[Freeradius Active Directory Integration]]<br />
<br />
== Web Applications ==<br />
* [[2600hz]] ''FreeSWITCH, Asterisk GUI web acces tool.''<br />
* [[Awstats]] ''Free log file analyzer.''<br />
* [[Drupal]] ''Content Management System (CMS) written in PHP.''<br />
* [[EyeOS]] ''Cloud Computing Desktop.''<br />
* [[FreePBX_V3]] ''FreeSWITCH, Asterisk GUI web acces tool.''<br />
* [[Glpi]] ''Information Resource-Manager.''<br />
* [[MediaWiki]] ''Free web-based wiki software application''<br />
* [[Phpizabi]] ''Social Networking Platform.''<br />
* [[PhpPgAdmin]] ''Web-based administration tool for PostgreSQL.''<br />
* [[Phpmyadmin]] ''Web-based administration tool for MYSQL.''<br />
* [[Redmine]] ''Project management system''<br />
* [[Statusnet]] ''Microblogging Platform.''<br />
* [[Sqstat]] ''Script to look active squid users connections.''<br />
* [[Webmin]] ''A web-based interface for Linux system.''<br />
* [[WordPress]] ''Web software to create website or blog. ''<br />
<br />
== Monitoring ==<br />
* [[Traffic monitoring]] ''(For Alpine Linux firewalls)''<br />
* [[Setting up traffic monitoring using rrdtool (and snmp)]]<br />
* [[Setting up Smokeping]] ''(Smokeping network latency monitoring)''<br />
* [[Setting up Cacti]]<br />
* [[Setting up NRPE daemon]] ''(Performs remote Nagios checks)''<br />
* [[Setting up Zabbix]]<br />
* [[Setting Up Fprobe And Ntop]] ''NetFlow collection and analysis''<br />
<br />
== Misc ==<br />
* [[Setting up lm_sensors]]<br />
* [[Formatting HD/Floppy/Other]]<br />
* [[Screen on console]]<br />
* [[Using espeak on Alpine Linux]]<br />
* [[IPTV How To]]<br />
* [[Pllua]]<br />
<br />
== Drafts ==<br />
Those are not finished yet.<br />
* [[AlpineSystem:CoLinux_Setup | Installing Alpine on CoLinux ]]<br />
* [[Using Racoon for Remote Sites]]<br />
* [[High Performance and Fault Tolerant Routing with Alpine Linux]]<br />
* [[Setting up Transparent Squid Proxy]] ''(Covers Squid proxy and URL Filtering system)''<br />
** [[Obtaining user information via SNMP]] ''(Using the Squark Squid authentication helper)''<br />
* [[Setting up Streaming an Asterisk Channel]]<br />
* [[Setting up A Network Monitoring and Inventory System]] ''((Nagios + OpenAudit and related components)''<br />
* [[Intrusion Detection using Snort]] ''Installing and configuring Snort and related applications on Alpine 2.0.x''<br />
* [[IP Accounting]] ''Installing and configuring pmacct for IP Accounting, Netflow/sFlow collector''<br />
* [[Howto Setup a Wireless Access Point]] ''Setting up Secure Wireless AP w/ WPA encryption with bridge to wired network''<br />
<br />
== Obsolete Docs ==<br />
Those are candidates for rewriting/removal.<br />
* [[Bootstrapping Alpine on Soekris net4xxx]]<br />
* [[Bootstrapping Alpine on PC Engines ALIX.3]]<br />
* [[Setting up a /var partition on software IDE raid1]]<br />
* [[Native Harddisk Install]]<br />
* [[Installing XUbuntu using Alpine boot floppy]]<br />
* [[Setting up trac wiki]]</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Pllua&diff=4765Pllua2011-01-06T17:37:46Z<p>Aalatchm: new page</p>
<hr />
<div>= How to Install and Use PL/Lua =<br />
<br />
# Install PL/Lua<br />
apk add pllua<br />
# Install PL/Lua on your database.<br />
psql -U postgres -f /usr/share/postgresql/contrib/pllua.sql <DBNAME><br />
<br />
== Official Documentation ==<br />
<br />
Official documentation is found at http://pllua.projects.postgresql.org/.<br />
<br />
== Additional Functions ==<br />
<br />
These functions may not be listed in other documentation, but were found by printing entries in _G in a PL/Lua trigger.<br />
_PLVERSION PL/Lua<br />
fromstring function:<br />
info function:<br />
log function:<br />
notice function:<br />
server table:<br />
setshared function:<br />
shared table:<br />
trigger table:<br />
warning function:</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=LuaPosix&diff=4652LuaPosix2010-11-30T12:11:14Z<p>Aalatchm: added posix.pipe, with basic example</p>
<hr />
<div>This is a list of the Lua Posix functions. Included is helpful snippets of code.<br />
Install lua posix. To get this list do:<br />
require "posix"<br />
for a in pairs(posix) do <br />
print(a)<br />
end<br />
<br />
=access=<br />
check real user's permissions for a file<br />
<br />
====Synopsis====<br />
posix.access(''pathname'', ''mode'')<br />
<br />
====Description====<br />
<br />
'''access()''' checks whether the calling process can access the file ''pathname''. If pathname is a symbolic link, it is dereferenced.<br />
<br />
The mode specifies the accessibility check(s) to be performed, and is either the string '''"f"''', or one or more of '''"r"''', '''"w"''', and '''"x"'''. '''"f"''' tests for the existence of the file. '''"r"''', '''"w"''', and '''"x"''' test whether the file exists and grants read, write, and execute permissions, respectively.<br />
<br />
====Return Value====<br />
<br />
On success (all requested permissions granted), zero is returned. On error (at least one char in mode asked for a permission that is denied, or some other error occurred), nil, errorstr and errno is returned.<br />
<br />
====Examples====<br />
<br />
status, errstr, errno = posix.access("/etc/passwd", "rw")<br />
<br />
if not posix.access("/foo", "f") then<br />
print("/foo does not exist")<br />
end<br />
<br />
====References====<br />
<br />
http://swoolley.org/man.cgi/access<br />
<br />
=chdir=<br />
change working directory<br />
<br />
====Synopsis====<br />
posix.chdir(''path'')<br />
<br />
====Return Value====<br />
On success, zero is returned. On error, nil, an error string and errno is returned.<br />
<br />
====Examples====<br />
status, errstr, errno = posix.chdir("/tmp")<br />
<br />
if posix.chdir("/tmp") then<br />
print("Changed current working dir to:", posix.getpwd())<br />
fi<br />
<br />
=chmod=<br />
change permissions of a file<br />
<br />
====Synopsis====<br />
posix.chmod(''path'', ''mode'')<br />
<br />
====Description====<br />
The mode of the file given by ''path'' is changed.<br />
<br />
Modes are specified in one of the following formats<br />
* "rwxrwxrwx" (i.e "rw-rw-w--")<br />
* "ugoa+-=rwx" (i.e "u+w")<br />
* "+-=rwx" (i.e "+w")<br />
<br />
====Return Value====<br />
On success, zero is returned. On error, nil, errstr and errno is returned.<br />
<br />
====Examples====<br />
posix.chmod("/tmp", "a+rwx")<br />
<br />
status, errstr = posix.chmod(file, "-w")<br />
if not status then<br />
print(errstr)<br />
fi<br />
<br />
=chown=<br />
'''INPUT'''<br />
*Path-location of file or directory<br />
* UID - User id number<br />
* GID - Group id number<br />
'''OUPUT'''<br />
*String - 0 is success and nil for failure<br />
bar = require "posix"<br />
print(bar.chown("/etc/passwd",100,200)<br />
--above will give back nil. Since we printed it will also give back the system errors.<br />
<br />
=clock_getres=<br />
'''TODO'''<br />
<br />
=clock_gettime=<br />
'''TODO'''<br />
<br />
=crypt=<br />
password and data encryption<br />
====Synopsis====<br />
posix.crypt(''string'', ''salt'')<br />
<br />
====Return Value====<br />
On success, zero is returned. On error, nil, an error string and errno is returned.<br />
<br />
<br />
<br />
=ctermid=<br />
'''INPUT'''<br />
*NONE- DISPLAYS the terminal id<br />
'''OUTPUT'''<br />
*String with the terminal id<br />
bar = require "posix"<br />
print(bar.ctermid())<br />
<br />
=dir=<br />
read a directory<br />
<br />
====Synopsis====<br />
posix.dir(''path'')<br />
<br />
====Description====<br />
Reads directory ''path'', and returns a table with all the files. If ''path'' is omitted, current working dir is read.<br />
<br />
====Return Value====<br />
'''posix.dir()''' returns a table with all filenames on succes. On error, nil, an error string and errno is returned.<br />
<br />
====Examples====<br />
files, errstr, errno = posix.dir("/var/log")<br />
if files then<br />
for a,b in ipairs(files) do<br />
print(b)<br />
end<br />
else<br />
print(errstr)<br />
end<br />
<br />
=dup=<br />
duplicate a file descriptor<br />
<br />
====Synopsis====<br />
posix.dup(''oldfd''[, ''newfd''])<br />
<br />
====Description====<br />
'''posix.dup()''' creates a copy of the file descriptor ''oldfd''.<br />
<br />
''newfd'' will be the copy of ''oldfd'', closing ''newfd'' first if necessary. <br />
<br />
If ''newfd'' is omitted, the lowest-numbered unused descriptor will be used for the new descriptor.<br />
<br />
====Return Value====<br />
'''posix.dup()''' returns the new descriptor, or nil, an error string and errno if an error occured.<br />
<br />
=errno=<br />
<br />
Display the error information<br />
<br />
'''INPUT'''<br />
*NONE<br />
'''OUPUT'''<br />
*Success, or Error message<br />
bar = require "posix"<br />
a,b = bar.dir("/var/foo"), bar.errno()<br />
print(a,b)<br />
-- a will be nil or 0, b will be No such file or directory or Success<br />
<br />
=exec=<br />
execute a file<br />
====Synopsis====<br />
posix.exec(path,[args])<br />
<br />
====Description====<br />
'''exec'''() replaces the current process image with a new process image.<br />
<br />
====Return Value====<br />
On success '''exec'''() will not return. On error nil, errstr and errno is returned.<br />
<br />
=execp=<br />
execute a file using PATH environment variable<br />
====Synopsis====<br />
posix.execp(path,[args])<br />
<br />
====Description====<br />
'''execp'''() replaces the current process image with a new process image. If ''path'' does not contain a slash (/) character the file wil be searched for in PATH environment variable.<br />
<br />
====Return Value====<br />
On success '''execp'''() will not return. On error nil, errstr and errno is returned.<br />
<br />
<br />
=mkfifo=<br />
'''INPUT'''<br />
*PATH- where to make the fifo<br />
'''OUPUT'''<br />
* 0 for success, nil for failure<br />
<br />
bar = require "posix"<br />
print(bar.mkfifo("/tmp/bobo"))<br />
--Returns 0 for success, nil for failure<br />
<br />
=files=<br />
Returns an interator function that loops over each file in the given directory<br />
<br />
'''INPUT'''<br />
*PATH- Directory<br />
'''OUPUT'''<br />
require "posix"<br />
<br />
for name in posix.files("/etc") do<br />
print (name)<br />
end<br />
<br />
=fork=<br />
'''INPUT'''<br />
*None<br />
'''OUTPUT'''<br />
returns: -1 on error, 0 to the child process, and the pid of the child to the parent.<br />
<br />
require("posix")<br />
<br />
print ("parent: my pid is: " .. posix.getpid("pid")) <br />
<br />
local pid = posix.fork () <br />
<br />
if ( pid == -1 ) then<br />
print ("parent: The fork failed.")<br />
elseif ( pid == 0 ) then<br />
print ("child: Hello World! I am pid: " .. posix.getpid("pid") )<br />
print ("child: I'll sleep for 1 second ... ")<br />
posix.sleep(1)<br />
print ("child: Good bye");<br />
else<br />
print ("parent: While the child sleeps, I'm still running.")<br />
print ("parent: waiting for child (pid:" .. pid .. ") to die...")<br />
posix.wait(pid)<br />
print ("parent: child died, but I'm still alive.")<br />
print ("parent: Good bye")<br />
end<br />
<br />
parent: my pid is: 11050<br />
child: Hello World! I am pid: 11051<br />
child: I'll sleep for 1 second ... <br />
parent: While the child sleeps, I'm still running.<br />
parent: waiting for child (pid:11051) to die...<br />
child: Good bye<br />
parent: child died, but I'm still alive.<br />
parent: Good bye<br />
<br />
=gmtime=<br />
'''TODO'''<br />
<br />
=getcwd=<br />
Get current working directory<br />
'''INPUT'''<br />
*NONE<br />
'''OUTPUT'''<br />
*String- contents of which is the current working directory<br />
require "posix"<br />
print(posix.getcwd())<br />
<br />
=getenv=<br />
'''INPUT'''<br />
*NONE<br />
'''OUPUT'''<br />
*Table - Current Environment settings<br />
<br />
bar = require "posix"<br />
bobo = bar.getenv()<br />
for a,b in pairs(bobo) do print(b) end<br />
-- Varible - Value<br />
<br />
=getgroup=<br />
'''INPUT'''<br />
*GID, or groupname<br />
'''OUPUT'''<br />
*TABLE -contents of which hold the group name,gid, and users<br />
bar = require "posix"<br />
bobo = bar.getgroup(1000)<br />
for a,b in pairs(bobo) do print(a,b) end<br />
--if you use pairs then bobo will print also the name and gid or the group<br />
--if you use ipairs then just the group members<br />
1 user1<br />
2 user2<br />
name wheel<br />
gid 1<br />
<br />
=getlogin=<br />
get user name<br />
<br />
====Synopsis====<br />
posix.getlogin()<br />
<br />
====Description====<br />
<br />
'''getlogin()''' returns a string containing the name of the user logged in on the controlling terminal of the process, or nil if this information cannot be determined.<br />
<br />
====Examples====<br />
<br />
print(posix.getlogin())<br />
<br />
=getrlimit=<br />
'''TODO'''<br />
<br />
=getpasswd=<br />
get password file entry<br />
<br />
====Synopsis====<br />
posix.getpasswd(''user'', ''field'')<br />
<br />
====Description====<br />
<br />
'''getpasswd()''' queries the local /etc/passwd database. ''user'' can be either an uid or a username. ''field'' is a string of one of '''"uid"''', '''"name"''', '''"gid"''', '''"password"''', '''"gecos"''', '''"dir"''' or '''"shell"'''.<br />
<br />
====Return Value====<br />
<br />
Returns the value of ''field'' for ''user''. If ''field'' is omitted, a table with all fields is returned.<br />
<br />
====Examples====<br />
<br />
for a,b in pairs(posix.getpasswd("root")) do<br />
print(a,b)<br />
end<br />
<br />
Output:<br />
uid 0<br />
name root<br />
gid 0<br />
passwd x<br />
gecos root<br />
dir /root<br />
shell /bin/bash<br />
<br />
print(posix.getpasswd("root", "shell"))<br />
Output:<br />
/bin/sh<br />
<br />
=getprocessid=<br />
'''INPUT'''<br />
*Selector - either [egid,euid,gid,uid,pgrp,pid,ppid,NULL]<br />
'''OUPUT'''<br />
*Number that matches the current process and the selector<br />
bar = require "posix"<br />
print(bar.getprocessid("gid"))<br />
18456 <br />
--it just printed the current process id for the script or interactive lua.<br />
<br />
<br />
Is there a version difference here? AL 1.7.7 calls this "getpid" [[User:Nangel|Nangel]]<br />
<br />
=gettimeofday=<br />
'''TODO'''<br />
<br />
=glob=<br />
find pathnames matching a pattern<br />
====Synopsis====<br />
posix.glob(''pattern'')<br />
<br />
====Description====<br />
The '''glob'''() function searches for all the pathnames matching ''pattern'' according to the rules used by the shell.<br />
<br />
====Return Value====<br />
On successful comlpetion, '''glob'''() returns a table with the filenames. On error '''glob'''() returns nil, errstr and errno.<br />
<br />
====Examples====<br />
for i,j in pairs(posix.glob("/proc/[0-9]*/exe")) do<br />
local f = posix.readlink(j)<br />
if f then<br />
print(f)<br />
end<br />
end<br />
<br />
=kill=<br />
'''INPUT'''<br />
*PID- process identifier<br />
*Signal- to send to the process<br />
'''OUPUT'''<br />
<br />
bar = require "posix"<br />
--kill your current process<br />
bobo = bar.getprocessid("pid")<br />
bar.kill(bobo,9)<br />
---Signals looks to be the number signals accepted in Unix<br />
<br />
=link=<br />
make a new name for a file<br />
====Synopsis====<br />
posix.dup(''oldpath'', ''newpath''[, ''symbolic''])<br />
<br />
====Description====<br />
Creates a new name to an existing file. If ''symbolic'' is true the new name will be a symbolic link (soft link), otherwise it will be a hard link.<br />
<br />
====Return Value====<br />
On success, zero is returned. On error '''link'''() returns nil, errstr and errno.<br />
<br />
====Examples====<br />
require "posix"<br />
source="/etc/passwd"<br />
dest="testfile"<br />
status, errstr = posix.link(source, dest, true)<br />
if status == nil then<br />
io.stderr:write(dest..": "..errstr.."\n")<br />
end<br />
<br />
<br />
=localtime=<br />
'''TODO'''<br />
<br />
=mkdir=<br />
create a directory<br />
====Synopsis====<br />
posix.dup(''pathname'')<br />
<br />
====Descritption====<br />
'''mkdir'''() attempts to create a directory named pathname.<br />
<br />
====Return Value====<br />
'''glob'''() returns 0 on success, or nil, errstr and errno on error.<br />
<br />
====Example====<br />
require "posix"<br />
newdir = "/home/user/bobo"<br />
status, errstr = posix.mkdir(newdir)<br />
if status == nil then<br />
io.stderr:write(newdir..": "..errstr.."\n")<br />
end<br />
<br />
<br />
=pathconf=<br />
get configuration values for files<br />
<br />
====Synopsis====<br />
posix.pathconf(''path'', ''name'')<br />
<br />
====Description====<br />
<br />
'''posix.pathconf()''' gets a value for configuration option ''name'' for the filename ''path''. Setting ''name'' equal to one of the following strings returns the following configuration options:<br />
<br />
* '''link_max'''<br />
** returns the maximum number of links to the file. If ''path'' refer to a directory, then the value applies to the whole directory.<br />
* '''max_canon'''<br />
** returns the maximum length of a formatted input line, where ''path'' must refer to a terminal.<br />
* '''max_input'''<br />
** returns the maximum length of an input line, where ''path'' must refer to a terminal.<br />
* '''name_max'''<br />
** returns the maximum length of a filename in the directory ''path'' the process is allowed to create.<br />
* '''path_max'''<br />
** returns the maximum length of a relative pathname when ''path'' is the current working directory.<br />
* '''pipe_buf'''<br />
** returns the size of the pipe buffer, where ''path'' must refer to a FIFO.<br />
* '''chown_restricted'''<br />
** returns non-zero if the chown(2) call may not be used on this file. If ''path '' refer to a directory, then this applies to all files in that directory.<br />
* '''no_trunc'''<br />
** returns non-zero if accessing filenames longer than '''name_max''' generates an error.<br />
* '''vdisable'''<br />
** returns non-zero if special character processing can be disabled, where ''path'' must refer to a terminal.<br />
<br />
====Return Value====<br />
<br />
The limit is returned, if one exists. If ''name'' is omitted, a table of all limits is returned.<br />
<br />
====Examples====<br />
for i,j in pairs(posix.pathconf("/dev/tty" )) do<br />
print(i, j)<br />
end<br />
Will ouput:<br />
pipe_buf 4096<br />
link_max 127<br />
path_max 4096<br />
max_canon 255<br />
chown_restricted 1<br />
no_trunc 1<br />
max_input 255<br />
name_max 255<br />
vdisable 0<br />
<br />
====References====<br />
<br />
http://swoolley.org/man.cgi/pathconf<br />
<br />
=pipe=<br />
'''TODO'''<br />
====Example====<br />
require "posix"<br />
rd, wr = posix.pipe()<br />
wr:write("hello, world\n")<br />
wr:close()<br />
print(rd:read("*all"))<br />
rd:close()<br />
<br />
=putenv=<br />
'''INPUT'''<br />
*STRING-<br />
'''OUPUT'''<br />
* 0 if success, nil if not<br />
<br />
require "posix"<br />
posix.putenv("DISPLAY=localhost:0")<br />
<br />
=readlink=<br />
'''INPUT'''<br />
*PATH-path to link<br />
'''OUPUT'''<br />
* 0 if success, nil if failure<br />
require "posix"<br />
posix.readlink("/etc/rc.d/postfix")<br />
--0 if sucess, nil if failed<br />
<br />
=rmdir=<br />
'''INPUT'''<br />
*PATH- path to directory<br />
'''OUPUT'''<br />
* 0 for sucess<br />
* nil for failure<br />
require "posix"<br />
posix.rmdir("/home/testdir")<br />
-- 0 for success, nil for failure<br />
<br />
=setgid=<br />
'''INPUT'''<br />
*Group<br />
** Name or GID<br />
'''OUPUT'''<br />
* 0 for sucess<br />
* nil for failure<br />
<br />
require "posix"<br />
posix.setgid("1000")<br />
<br />
=setlogmask=<br />
'''TODO'''<br />
<br />
=setrlimit=<br />
'''TODO'''<br />
<br />
=setuid=<br />
'''INPUT'''<br />
*User<br />
** Name or UID<br />
'''OUPUT'''<br />
*0 for sucess, nil for failure<br />
<br />
require "posix"<br />
posix.setuid("1000")<br />
-- 0 for sucess, nil for failure<br />
<br />
=sleep=<br />
'''INPUT'''<br />
*SECONDS<br />
'''OUPUT'''<br />
*0 for sucess, nil for failure<br />
<br />
require "posix"<br />
posix.sleep(5)<br />
-- will sleep for 5 seconds, usually will not fail<br />
<br />
=stat=<br />
'''INPUT'''<br />
*PATH - location of file or direcory<br />
*Selector - <br />
**dev<br />
**type<br />
**ctime<br />
**nlink<br />
**atime<br />
**uid<br />
**mtime<br />
**gid<br />
**mode<br />
**ino<br />
**size<br />
'''OUPUT'''<br />
*If no mode will output as a table with each of the above set<br />
*If mode is set then will give a string with value<br />
<br />
require "posix"<br />
bar = posix.stat("/etc/")<br />
for a,b in pairs(bar) do print(a,b) end<br />
dev 769<br />
type directory<br />
ctime 1194624026<br />
nlink 113<br />
atime 1194866712<br />
uid 0<br />
mtime 1194624026<br />
gid 0<br />
mode rwxr-xr-x<br />
ino 4<br />
size 6208<br />
<br />
=sysconf=<br />
'''INPUT'''<br />
*Accept a selector if given anything<br />
**tzname_max<br />
**clk_tck<br />
**stream_max<br />
**ngroups_max<br />
**child_max<br />
**open_max<br />
**saved_ids<br />
**job_control<br />
**version<br />
**arg_max<br />
'''OUPUT'''<br />
*TABLE - if no selector<br />
*STRING - if 1 selector<br />
<br />
require "posix"<br />
bar = posix.stat()<br />
for a,b in pairs(bar) do print(a,b) end<br />
tzname_max 6<br />
clk_tck 100<br />
stream_max 16<br />
ngroups_max 65536<br />
child_max 999<br />
open_max 1024<br />
saved_ids 1<br />
job_control 1<br />
version 200112<br />
arg_max 131072<br />
<br />
=strftime=<br />
'''TODO'''<br />
<br />
=time=<br />
'''TODO'''<br />
<br />
=times=<br />
'''INPUT'''<br />
*<br />
**utime<br />
**cstime<br />
**elapsed<br />
**cutime<br />
**stime<br />
'''OUPUT'''<br />
*TABLE - if non specified output all values in a table<br />
*STING - if one of the above is specified string output<br />
<br />
require "posix"<br />
bar = posix.times()<br />
for a,b in pairs(bar) do print(a,b) end<br />
--Maybe takes function calls to see how long they run<br />
<br />
=ttyname=<br />
'''INPUT'''<br />
*NONE<br />
'''OUPUT'''<br />
*STRING - what tty am I on<br />
<br />
require "posix"<br />
print(posix.ttyname())<br />
<br />
=umask=<br />
'''INPUT'''<br />
*NONE<br />
** or mode, what to change the umask to<br />
'''OUPUT'''<br />
*STRING - what is the current umask set to<br />
** or mode, what to change is to<br />
<br />
require "posix"<br />
print(posix.umask)<br />
-- rwxr-xr-x<br />
--or change it<br />
posix.umask("a=rwx")<br />
print(posix.umask())<br />
-- rwxrwxrwx<br />
<br />
= uname =<br />
get name and information about current kernel<br />
<br />
====Synopsis====<br />
posix.access(''[format]'')<br />
<br />
====Description====<br />
<br />
'''uname()''' returns the string ''format'' with directives prefixed by '%' replaced with specified systrem information. If ''format'' is not specified or is nil, then the string "%s %n %r %v %m" will be used.<br />
<br />
The format string directives are:<br />
<br />
%s - kernel name<br />
%n - network node hostname<br />
%r - kernel release<br />
%v - kernel version<br />
%m - machine hardware name<br />
<br />
====Return Value====<br />
<br />
A string with the formatted system information.<br />
<br />
====Examples====<br />
<br />
print("Kernel version is: "..posix.uname("%v"))<br />
<br />
====References====<br />
http://swoolley.org/man.cgi?q=2+uname<br />
<br />
=utime=<br />
'''INPUT'''<br />
*Path-location of file or directory<br />
**atime - access time<br />
**mtime - modification time<br />
'''OUPUT'''<br />
* 0 for sucess<br />
* nil for failure<br />
<br />
require "posix"<br />
posix.utime("/var/log/test",atime,mtime)<br />
<br />
=wait=<br />
'''INPUT'''<br />
*PID - process id<br />
'''OUPUT'''<br />
* 0 for success<br />
* nil for failure<br />
<br />
require "posix"<br />
posix.wait(10)<br />
<br />
----<br />
<br />
'''If you are using this under linux also get '''<br />
<br />
=setenv=<br />
'''INPUT'''<br />
*Name- Name of Varible<br />
*Value- What the Name varible should be set to<br />
**overwrite- is this overwriting one already set<br />
'''OUPUT'''<br />
* 0 for sucess, nil for failure<br />
<br />
require "posix"<br />
posix.setenv("BAR","YES")<br />
<br />
=unsetenv=<br />
'''INPUT'''<br />
*NAME - name of the varible to unset<br />
'''OUPUT'''<br />
* 0 for sucess, nil for failure<br />
<br />
require "posix"<br />
posix.unsetenv("BAR")</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Setting_up_a_software_RAID_array&diff=4525Setting up a software RAID array2010-10-19T14:41:49Z<p>Aalatchm: tested on alpine-2.0.2. Should it still be marked obsolete?</p>
<hr />
<div>{{Obsolete}}<br />
[[Category:Storage]]<br />
This document will show how to create hard disk mirroring using cheap IDE disks.<br />
<br />
This document was written for alpine-1.3.8 or later. It is tested with alpine-1.7.7. It is tested with alpine 1.8.1.1. It is tested with alpine-2.0.2<br />
<br />
I will setup 1 raid device for use as physical storage for [[Setting up Logical Volumes with LVM | lvm]] .<br />
<br />
== Loading needed modules ==<br />
Start with loading the ide-disk and raid1 kernel modules. If you use SATA or SCSI disks you will not need the ide-disk module.<br />
<br />
modprobe ide-disk<br />
modprobe raid1<br />
<br />
Add them to /etc/modules so they get loaded during next reboot.<br />
<br />
echo ide-disk >> /etc/modules<br />
echo raid1 >> /etc/modules<br />
<br />
== Creating the partitions ==<br />
I will use /dev/hde and /dev/hdg in this document but you will probably use /dev/hda and /dev/hdc. Note that the disks should not be connected on the same IDE bus (sharing the same IDE cable). To find what disks you have available, look in /proc/partitions or look at the /dev/disk* links that the mdev system has created.<br />
ls -l /dev/disk*<br />
lrwxrwxrwx 1 root root 3 Oct 17 13:23 /dev/disk -> hda<br />
lrwxrwxrwx 1 root root 3 Oct 17 13:23 /dev/disk0 -> hda<br />
lrwxrwxrwx 1 root root 3 Oct 17 13:23 /dev/disk1 -> hdc<br />
<br />
Create the partitions using fdisk.<br />
<br />
fdisk /dev/hda<br />
<br />
I will create one single partition of type Linux raid autodetect. Use '''n''' in fdisk to create the partition and '''t''' to set type. Logical volumes will be created later. My partition table looks like this ('p' to print partition table):<br />
<br />
Device Boot Start End Blocks Id System<br />
/dev/hda1 1 17753 8388261 fd Linux raid autodetect<br />
<br />
Use '''w''' to '''w'''rite and quit.<br />
Do the same with your second disk.<br />
<br />
fdisk /dev/hdc<br />
<br />
Mine looks like this:<br />
Device Boot Start End Blocks Id System<br />
/dev/hdc1 1 17753 8388261 fd Linux raid autodetect<br />
<br />
== Setting up the raid array ==<br />
Install mdadm to set up the arrays.<br />
<br />
apk_add mdadm<br />
<br />
In alpine 1.8.1.1 you have to run "mdev -s" to update your /dev entries.<br />
<br />
If you use an alpine version earlier than 1.7.3 you need to make the /dev nodes before creating the arrays.<br />
<br />
mknod /dev/md0 b 9 0<br />
<br />
<br />
Create the array.<br />
mdadm --create --level=1 --raid-devices=2 /dev/md0 /dev/hda1 /dev/hdc1<br />
<br />
== Monitoring sync status ==<br />
You should now be able to see the array syncronize by looking at the contents of /proc/mdstat.<br />
<br />
~ # cat /proc/mdstat <br />
Personalities : [raid1] <br />
md0 : active raid1 hdc1[1] hda1[0]<br />
8388160 blocks [2/2] [UU]<br />
[=========>...........] resync = 45.3% (3800064/8388160) finish=0.3min speed=200003K/sec<br />
<br />
unused devices: <none><br />
<br />
You don't need to wait til it is fully syncronized to continue.<br />
<br />
== Saving config ==<br />
Create the /etc/mdadm.conf file so mdadm knows how your raid setup is:<br />
mdadm --detail --scan > /etc/mdadm.conf<br />
<br />
To make sure the raid devices start during the next reboot run:<br />
rc-update add mdadm-raid<br />
Or, on Alpine 1.8 or earlier:<br />
rc_add -s 10 -k mdadm-raid<br />
<br />
The ''-s 10'' option is to make sure that the raid arrays are started early, before things like lvm and localmount.<br />
<br />
Use ''lbu commit'' as usual to save configs to usb or floppy.<br />
<br />
The raid device /dev/md0 is now ready to be used with [[Setting up Logical Volumes with LVM|lvm]] or mkfs.</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Setting_up_trac_wiki&diff=4061Setting up trac wiki2010-07-16T08:28:13Z<p>Aalatchm: added instructions to install SVN and connect it in Trac installation</p>
<hr />
<div>This document describes how to set up a [http://trac.edgewall.org Trac] wiki. It is based on alpine 1.10.6 and should also be compatible with newer version.<br />
<br />
== General notes on this tutorial ==<br />
In this tutorial we use these settings. These values will re-appear in various places in the upcoming example.<BR><br />
You can use whatever settings you like.<br />
{| style="width: 450px; background-color: #f8f8f8; border: 1px #ccc solid;"<br />
|'''Path to Trac project:'''<br />
|/var/lib/trac/myproject<br />
|-<br />
|'''Username:'''<br />
|tracadmin<br />
|-<br />
|'''Realm:'''<br />
|example.com<br />
|-<br />
|'''Password:'''<br />
|secret<br />
|-<br />
|'''Password file:'''<br />
|/var/lib/trac/myproject/users.realm<br />
|-<br />
|'''Subversion path'''<br />
|/var/lib/subversion/myproject<br />
|}<br />
<br />
== Installing Trac ==<br />
{{Cmd|apk add trac}}<br />
<br />
== Create a Subversion repository ==<br />
Next we create an SVN repository to be connected to Trac:<br />
{{Cmd|mkdir /var/lib/subversion}}<br />
{{Cmd|svnadmin create /var/lib/subversion/myproject}}<br />
<br />
== Creating a Project Environment ==<br />
Now lets initiate the environment<br />
{{Cmd|trac-admin /var/lib/trac/myproject initenv}}<br />
* Enter some project name when prompted<br />
* Leave default sqlite DB (just press enter)<br />
* Enter 'svn' as repository type<br />
* Enter subversion repository path: /var/lib/subversion/myproject<br />
<br />
== Configuring Authentication/Security ==<br />
=== Create password-file ===<br />
You need to create a password file containing this information<br />
{{Cmd|<nowiki>echo -n "tracadmin:example.com:secret" | md5sum >> /var/lib/trac/myproject/users.htdigest</nowiki>}}<br />
Now you need to edit the passwordfile '/var/lib/trac/myproject/users.htdigest' and append the username and realm in plaintext.<br />
tracadmin:example.com:72842d9ffe3f4f63306a06756d2953ee<br />
{{Note|Note that you need to remove the "-" and whitespaces at the end of the row.}}<br />
<br />
=== Admin-rights ===<br />
Next is to give admin-rights to your 'tractester' account<br />
{{Cmd|trac-admin /var/lib/trac/myproject permission add tractester TRAC_ADMIN}}<br />
<br />
== Running/Testing the Standalone Server ==<br />
Lets test if your password-file and other configurations worked as they are supposed to.<BR><br />
In case something is broken, this test would give you a hint on what's wrong.<br />
{{Cmd|<nowiki>tracd --port 8000 --auth=*,/var/lib/trac/myproject/users.htdigest,example.com /var/lib/trac/myproject</nowiki>}}<br />
<br />
Try connect to trac with webbrowser on http://localhost:8000<br />
<br />
== Configuration/Startup ==<br />
Edit '/etc/conf.d/tracd' and configure your variables<br />
TRACD_PORT="80"<br />
TRACD_OPTS="--auth=*,/var/lib/trac/myproject/users.htdigest,example.com /var/lib/trac/myproject"<br />
<br />
Set ownership to be tracd<br />
{{Cmd|chown -R tracd:tracd /var/lib/trac}}<br />
<br />
== Configuration/Startup ==<br />
Now you could start customizing your trac by editing '/var/lib/trac/myproject/conf/trac.ini'.<br />
<br />
== Startup ==<br />
Now it's time to fire up your trac.<br />
{{Cmd|/etc/init.d/tracd start}}<br />
<br />
== Backup ==<br />
To create a backup of a live TracEnvironment, simply run:<br />
{{Cmd|trac-admin /var/lib/trac/myproject hotcopy /path/to/backupdir}}<br />
<br />
== Boot ==<br />
Make it start during boot.<br />
{{Cmd|rc-update add tracd}}</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&diff=4015ISP Mail Server HowTo2010-06-28T08:23:55Z<p>Aalatchm: /* Install Dovecot */ convert username to lowercase so that UserName@domain.tld will work</p>
<hr />
<div>[[Category:mail]]<br />
== A Full Service Mail Server ==<br />
<br />
The goal of this document is to describe how to set up postfix, dovecot, clamav, dspam, roundecube, and postfixadmin for a full-featured "ISP" level mail server.<br />
<br />
The server must provide:<br />
<br />
* multiple virtual domains<br />
* admins for each domain (to add/remove virtual accounts)<br />
* Quota support per domain / account<br />
* downloading email via IMAP / IMAPS / POP3 / POP3S<br />
* relaying email for authenticated users with TLS or SSL (Submission / SMTPS protocol)<br />
* Standard filters (virus/spam/rbl/etc)<br />
* Web mail client<br />
* Value Add services<br />
<br />
== Set up Lighttpd + PHP ==<br />
<br />
PostfixAdmin needs php pgpsql and imap modules, so we do it in this step.<br />
<br />
apk add lighttpd php php-pgsql php-imap<br />
<br />
Stop and remove mini_httpd, and move ACF to lighttpd; We are setting this up to be a multi-domain virtual web server (replace host.example.com with the actual domain):<br />
<br />
mkdir -p /var/www/domains/host.example.com/www<br />
ln -s /usr/share/acf/www /var/www/domains/host.example.com/www/acf<br />
<br />
Edit /var/www/domains/host.example.com/index.html to put a simple redirection page:<br />
<br />
<pre><br />
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><br />
<html lang="en"><br />
<head><br />
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><br />
<title>host.example.com Redirector</title><br />
</head><br />
<body><br />
<ul><br />
<li><a href="/acf">ACF</a></li><br />
<li><a href="/postfixadmin">PostfixAdmin</a></li><br />
<li><a href="/roundcube">Roundcube</a></li><br />
</ul><br />
</body><br />
</pre><br />
<br />
Edit /etc/lighttpd/mod_cgi.conf to serve haserl files by adding a "" => "" cgi handler and to treat /acf/cgi-bin as a CGI directory (remove the '^')<br />
<br />
$HTTP["url"] =~ "/cgi-bin/" {<br />
# disable directory listings<br />
dir-listing.activate = "disable"<br />
# only allow cgi's in this directory<br />
cgi.assign = (<br />
".pl" => "/usr/bin/perl",<br />
".cgi" => "/usr/bin/perl",<br />
"" => ""<br />
)<br />
}<br />
<br />
Get a web certificate, and install it. You have two options: 1. If you want to use a self-signed cert, you can use the instructions found at [[Generating SSL certs with ACF]] or [[Generating SSL certs with ACF 1.9]] to generate it. 2. Use the certificate created with the '''setup-acf''' command. <br />
<br />
'''Option 1:'''<br />
If you create your own self-signed certificate, you can create the "server-bundle.pem" and the "ca-crt.pem" file with these commands:<br />
<br />
openssl pkcs12 -nokeys -cacerts -in certificate.pfx -out /etc/lighttpd/ca-crt.pem<br />
openssl pkcs12 -nodes -in certificate.pfx -out /etc/lighttpd/server-bundle.pem<br />
chown root:root /etc/lighttpd/server-bundle.pem<br />
chmod 400 /etc/lighttpd/server-bundle.pem<br />
<br />
'''Note:''' The server certificate ''and'' key are in the server-bundle.pem file, so it is critical that the file be read-only by user "root".<br />
<br />
'''Option 2:'''<br />
If you prefer to just use the default certificate created with the '''setup-acf''' command, then you will need to do the following:<br />
<br />
setup-acf<br />
<br />
During the above process, mini_httpd will be started, if it isn't already, and a certificate will be created. Once you have completed the setup-acf steps, do the following to move the certificate files to the correct location for lighttpd to use.<br />
<br />
mv /etc/ssl/mini_httpd/server.pem /etc/lighttpd/server-bundle.pem<br />
chown root:root /etc/lighttpd/server-bundle.pem<br />
chmod 400 /etc/lighttpd/server-bundle.pem<br />
<br />
Add these lines to /etc/lighttpd/lighttpd.conf to point to the new document root, and set it up to listen on port 443 (replace ''host.example.com'' with the actual domain and ''ip_address_of_server'' with the actual IP address):<br />
<br />
<pre><br />
<br />
simple-vhost.server-root = "/var/www/domains/"<br />
simple-vhost.default-host = "/host.example.com/"<br />
simple-vhost.document-root = "www/"<br />
<br />
$SERVER["socket"] == "ip_address_of_server:443" {<br />
ssl.engine = "enable"<br />
ssl.pemfile = "/etc/lighttpd/server-bundle.pem"<br />
}<br />
</pre><br />
<br />
If you went with Option 1 above, then add an additional line underneath the ssl.pemfile line, so that the section appears as follows:<br />
<br />
$SERVER["socket"] == "ip_address_of_server:443" {<br />
ssl.engine = "enable"<br />
ssl.pemfile = "/etc/lighttpd/server-bundle.pem"<br />
ssl.ca-file = "/etc/lighttpd/ca-crt.pem"<br />
}<br />
<br />
Ensure that the simple_vhosts module is loaded, as well as the cgi config scripts by uncommenting the following lines in /etc/lighttpd/lighttpd.conf<br />
<br />
server.modules = (<br />
# other modules may be listed<br />
"mod_simple_vhost", <br />
# other modules may be listed<br />
.<br />
.<br />
.<br />
include "mod_cgi.conf"<br />
<br />
include "mod_fastcgi.conf"<br />
<br />
Stop and remove mini_httpd; start lighttpd, test<br />
<br />
/etc/init.d/mini_httpd stop<br />
rc-update del mini_httpd<br />
apk del mini_httpd<br />
rc-update add lighttpd<br />
/etc/init.d/lighttpd start<br />
<br />
At this point you should be able to see ACF being served with lighttpd (Note: this will work well with alpine 1.10. With earlier versions there will be problems.) https://host.example.com/acf/<br />
<br />
== Install Postgresql ==<br />
<br />
Add and configure postgresql<br />
<br />
apk add acf-postgresql postgresql-client<br />
/etc/init.d/postgresql setup<br />
/etc/init.d/postgresql start<br />
rc-update add postgresql<br />
<br />
At this point any user can connect to the sql server with "trust" mechanism. If you want to enforce password authentication (you probably do) edit /var/lib/postgresql/8.4/data/pg_hba.conf<br />
<br />
<br />
Editme: What should we recommend?<br />
<br />
<br />
Create the postfix database:<br />
<br />
psql -U postgres<br />
create user postfix with password '******';<br />
create database postfix owner postfix;<br />
\c postfix<br />
create language plpgsql;<br />
\q<br />
<br />
(Of course, use your selected password where ******* is shown above.)<br />
<br />
== Install PostfixAdmin ==<br />
<br />
We are going to install the postfix admin web front-end before we install the mail server. This just creates an interface to populate the SQL tables that postfix and dovecot will use.<br />
<br />
Download PostfixAdmin from Sourceforge. When these instructions were written, 2.3 was the current release, so (replace host.example.com with the actual domain):<br />
wget http://downloads.sourceforge.net/project/postfixadmin/postfixadmin/postfixadmin_2.3.tar.gz<br />
tar zxvf postfixadmin_2.3.tar.gz<br />
mkdir -p /var/www/domains/host.example.com/www/postfixadmin<br />
mv postfixadmin-2.3/* /var/www/domains/host.example.com/www/postfixadmin<br />
rm -rf postfixadmin*<br />
<br />
Edit /var/www/domains/host.example.com/www/postfixadmin/config.inc.php and modify at least these lines (replace host.example.com with the actual domain):<br />
<br />
$CONF['configured'] = true;<br />
$CONF['setup_password'] = ""; << Don't change this yet<br />
$CONF['database_type'] = 'pgsql';<br />
$CONF['database_host'] = 'localhost';<br />
$CONF['database_user'] = 'postfix';<br />
$CONF['database_password'] = '*****'; << The password you chose above<br />
$CONF['database_name'] = 'postfix';<br />
$CONF['database_prefix'] = "";<br />
$CONF['admin_email'] = 'you@some.email.com'; << Your email address <br />
$CONF['encrypt'] = 'md5crypt';<br />
$CONF['authlib_default_flavor'] = 'md5raw';<br />
$CONF['dovecotpw'] = "/usr/sbin/dovecotpw";<br />
$CONF['domain_path'] = 'YES';<br />
$CONF['domain_in_mailbox'] = 'NO';<br />
$CONF['aliases'] = '10'; <br />
$CONF['mailboxes'] = '10';<br />
$CONF['maxquota'] = '10';<br />
$CONF['quota'] = 'YES';<br />
$CONF['quota_multiplier'] = '1024000';<br />
$CONF['vacation'] = 'NO'; <br />
$CONF['vacation_control'] ='NO';<br />
$CONF['vacation_control_admin'] = 'NO';<br />
$CONF['alias_control'] = 'YES';<br />
$CONF['alias_control_admin'] = 'YES';<br />
$CONF['special_alias_control'] = 'YES';<br />
$CONF['fetchmail'] = 'NO';<br />
$CONF['user_footer_link'] = "http://host.example.com/postfixadmin";<br />
$CONF['footer_link'] = 'http://host.example.com/postfixadmin/main.php';<br />
$CONF['create_mailbox_subdirs_prefix']=""; <br />
$CONF['used_quotas'] = 'YES'; <br />
$CONF['new_quota_table'] = 'YES'; <br />
<br />
You should further edit /var/www/domains/host.example.com/www/postfixadmin/config.inc.php and replace all instances of "change-this-to-your.domain.tld" with your actual mail domain. This can be done with busybox sed (replace example.com with your domain name):<br />
<br />
sed -i -e 's/change-this-to-your.domain.tld/example.com/g' /var/www/domains/host.example.com/www/postfixadmin/config.inc.php<br />
<br />
Go to http://host.example.com/postfixadmin/setup.php<br />
<br />
Create the password hash, add it to the config.inc.php file<br />
<br />
Go back to http://host.example.com/postfixadmin/setup.php<br />
<br />
Create superadmin account.<br />
<br />
== Install Postfix ==<br />
<br />
Create a user for the virtual mail delivery, and get its uid/gid (you'll need the numeric uid/gid for postfix)<br />
<br />
adduser vmail -H -D -s /bin/false<br />
grep vmail /etc/passwd<br />
<br />
(In examples below, we use 1006/1006 for the uid/gid)<br />
<br />
Create the mail directory, and assign vmail as the owner<br />
mkdir -p /var/mail/domains<br />
chown -R vmail:vmail /var/mail/domains<br />
<br />
<br />
Install postfix<br />
<br />
apk add acf-postfix postfix-pgsql<br />
<br />
Edit the /etc/postfix/main.cf file. Here's an example (don't forget to replace the uid/gid):<br />
<br />
myhostname=host.example.com<br />
mydomain=example.com<br />
<br />
mydestination = localhost.$mydomain, localhost<br />
mynetworks_style = subnet<br />
mynetworks = 127.0.0.0/8<br />
<br />
virtual_mailbox_domains = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_domains_maps.cf<br />
virtual_alias_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_maps.cf,<br />
proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_maps.cf,<br />
proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_catchall_maps.cf<br />
<br />
virtual_mailbox_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_mailbox_maps.cf,<br />
proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_mailbox_maps.cf<br />
<br />
virtual_mailbox_base = /var/mail/domains/<br />
virtual_gid_maps = static:1006<br />
virtual_uid_maps = static:1006<br />
virtual_minimum_uid = 100<br />
virtual_transport = virtual<br />
<br />
<br />
# This next command means you must create a virtual<br />
# domain for the host itself - ALL mail goes through<br />
# The virtual transport<br />
<br />
mailbox_transport = virtual<br />
local_transport = virtual<br />
local_transport_maps = $virtual_mailbox_maps<br />
<br />
smtpd_helo_required = yes<br />
disable_vrfy_command = yes<br />
message_size_limit = 10240000<br />
queue_minfree = 51200000<br />
<br />
smtpd_sender_restrictions =<br />
permit_mynetworks,<br />
reject_non_fqdn_sender,<br />
reject_unknown_sender_domain<br />
<br />
smtpd_recipient_restrictions =<br />
reject_non_fqdn_recipient,<br />
reject_unknown_recipient_domain,<br />
permit_mynetworks,<br />
permit_sasl_authenticated,<br />
reject_unauth_destination,<br />
reject_rbl_client dnsbl.sorbs.net,<br />
reject_rbl_client zen.spamhaus.org,<br />
reject_rbl_client bl.spamcop.net<br />
<br />
smtpd_data_restrictions = reject_unauth_pipelining<br />
<br />
# we will use this later - This prevents cleartext authentication<br />
# for relaying<br />
smtpd_tls_auth_only = yes<br />
<br />
<br />
Now we need to create a *bunch* of files so that postfix can get the delivery information out of sql. Here's a shell script to create the scripts. Change PGPW to the password for the postfix user of the postfix SQL database.<br />
<br />
cd /etc/postfix<br />
mkdir sql<br />
PGPW="ChangeMe"<br />
<br />
cat - <<EOF >sql/pgsql_virtual_alias_domain_catchall_maps.cf<br />
user=postfix<br />
password = $PGPW<br />
hosts = localhost<br />
dbname = postfix<br />
query = Select goto From alias,alias_domain where alias_domain.alias_domain = '%d' and alias.address = '@' || alias_domain.target_domain and alias.active = true and alias_domain.active= true <br />
EOF<br />
<br />
cat - <<EOF >sql/pgsql_virtual_alias_domain_mailbox_maps.cf<br />
user=postfix<br />
password = $PGPW<br />
hosts = localhost<br />
dbname = postfix<br />
query = Select maildir from mailbox,alias_domain where alias_domain.alias_domain = '%d' and mailbox.username = '%u' || '@' || alias_domain.target_domain and mailbox.active = true and alias_domain.active<br />
EOF<br />
<br />
cat - <<EOF >sql/pgsql_virtual_alias_domain_maps.cf<br />
user=postfix<br />
password = $PGPW<br />
hosts = localhost<br />
dbname = postfix<br />
query = select goto from alias,alias_domain where alias_domain.alias_domain='%d' and alias.address = '%u' || '@' || alias_domain.target_domain and alias.active= true and alias_domain.active= true<br />
EOF<br />
<br />
cat - <<EOF >sql/pgsql_virtual_alias_maps.cf<br />
user=postfix<br />
password = $PGPW<br />
hosts = localhost<br />
dbname = postfix<br />
query = Select goto From alias Where address='%s' and active ='1'<br />
EOF<br />
<br />
cat - <<EOF >sql/pgsql_virtual_domains_maps.cf<br />
user=postfix<br />
password = $PGPW<br />
hosts = localhost<br />
dbname = postfix<br />
query = Select domain from domain where domain='%s' and active='1'<br />
EOF<br />
<br />
cat - <<EOF >sql/pgsql_virtual_mailbox_maps.cf<br />
user=postfix<br />
password = $PGPW<br />
hosts = localhost<br />
dbname = postfix<br />
query = Select maildir from mailbox where username='%s' and active=true<br />
EOF<br />
<br />
chown -R postfix:postfix sql<br />
chmod 640 sql/*<br />
<br />
<br />
At this point you should be able to start up postfix<br />
<br />
newaliases # so postfix is happy...<br />
/etc/init.d/postfix start<br />
rc-update add postfix<br />
<br />
<br />
=== Create a domain in PostfixAdmin and test ===<br />
<br />
Go to http://host.example.com/postfixadmin/<br />
<br />
Log in using the superadmin account, create a domain for the local box (e.g. example.com), and create a user mailbox (e.g. root).<br />
<br />
From the machine, send a test message:<br />
<br />
sendmail -t root@example.com<br />
subject: test<br />
.<br />
^d<br />
<br />
<br />
In /var/log/mail.log (or /var/log/messages, if you still have busybox syslogd running) you should see the message queued. The message should be in /var/mail/domains/example.com/root/new<br />
<br />
== Install Dovecot ==<br />
<br />
Dovecot is the POP3/IMAP server to retrieve mail.<br />
<br />
As before, we install dovecot: <br />
<br />
apk add acf-dovecot dovecot-pgsql<br />
<br />
edit /etc/dovecot/dovecot.conf<br />
<br />
<pre><br />
# Select only the protocols you wish to support - all are listed in the next line<br />
protocols = imap imaps pop3 pop3s<br />
log_path = /var/log/dovecot.log<br />
info_log_path = /var/log/dovecot-info.log<br />
disable_plaintext_auth = no<br />
auth_username_format = %Lu<br />
<br />
# Authenticated IMAP<br />
ssl = yes<br />
ssl_cert_file = /etc/lighttpd/server-bundle.pem<br />
ssl_key_file = /etc/lighttpd/server-bundle.pem<br />
auth_verbose = yes<br />
auth_debug = no<br />
mail_location = maildir:/var/mail/domains/%d/%n<br />
auth default {<br />
mechanisms = plain<br />
passdb sql {<br />
args = /etc/dovecot/dovecot-sql.conf<br />
}<br />
userdb static {<br />
args = uid=1006 gid=1006 home=/var/mail/domains/%d/%n<br />
}<br />
}<br />
</pre><br />
<br />
Be sure to replace the uid and gid with the appropriate values for the vmail user.<br />
<br />
We need a certificate for SSL/TLS authentication, so in the example above, we use the lighttpd cert. That way when the cert is renewed/replaced, Dovecot will have access to the new cert as well. <br />
<br />
Create the /etc/dovecot/dovecot-sql.conf file:<br />
<br />
driver = pgsql<br />
connect = host=localhost dbname=postfix user=postfix password=********<br />
password_query = select username,password from mailbox where local_part = '%n' and domain = '%d'<br />
default_pass_scheme = MD5-CRYPT<br />
<br />
Again, change the password above to your postfix user password, and protect the file from prying eyes:<br />
<br />
chown root:root /etc/dovecot/dovecot-sql.conf<br />
chmod 600 /etc/dovecot/dovecot-sql.conf<br />
<br />
<br />
Start dovecot<br />
/etc/init.d/dovecot start<br />
rc-update add dovecot<br />
<br />
== Testing ==<br />
<br />
Make sure your firewall allows in ports 25(SMTP) 110 (POP3), 995 (POP3S), 143(IMAP), 993(IMAPS), or whatever subset you support. <br />
<br />
At this point, you should be able to:<br />
* Create a new domain and add users with PostfixAdmin<br />
* Send mail to those users via SMTP to port 25<br />
* Retrieve mail using the user's full email and password (e.g. username: user@example.com password: ChangeMe)<br />
<br />
== Value Add Features ==<br />
<br />
If you followed the guide above, you now have a functional mail server with many interconnected parts. The features below assume that the server is already running as described above. You should be able to add any or all of these features below to further enhance the mail service.<br />
<br />
<br />
=== Virus Scanning ===<br />
<br />
This procedure uses clamav and the postfix content_filter mechanism to scan inbound and outbound email for viruses. Infected emails are dropped. Clean emails are tagged with a "scanned by clamav" header.<br />
<br />
<br />
* Install clamav and clamsmtp:<br />
apk add acf-clamav clamsmtp<br />
* Edit the /etc/clamav/clamd.conf file if desired (not necessary in most cases)<br />
* Edit /etc/clamsmtpd.conf and verify the following lines<br />
OutAddress: 10026<br />
Listen: 127.0.0.1:10025 <br />
Header: X-Virus-Scanned: ClamAV using ClamSMTP<br />
Action: drop<br />
User: clamav <br />
* Start the daemons<br />
rc-update add clamd<br />
rc-update add clamsmtpd<br />
/etc/init.d/clamd start<br />
/etc/init.d/clamsmtpd start<br />
* Verify clamsmtp is listening on port 10025:<br />
netstat -anp | grep clamsmtp<br />
* [http://memberwebs.com/stef/software/clamsmtp/postfix.html Following the clamsmtp instructions]<br />
** edit /etc/postfix/main.cf and add:<br />
content_filter = scan:[127.0.0.1]:10025 <br />
** edit /etc/postfix/master.cf and add<br />
# AV scan filter (used by content_filter)<br />
scan unix - - n - 16 smtp<br />
-o smtp_send_xforward_command=yes<br />
-o smtp_enforce_tls=no<br />
# For injecting mail back into postfix from the filter<br />
127.0.0.1:10026 inet n - n - 16 smtpd<br />
-o content_filter=<br />
-o receive_override_options=no_unknown_recipient_checks,no_header_body_checks<br />
-o smtpd_helo_restrictions=<br />
-o smtpd_client_restrictions=<br />
-o smtpd_sender_restrictions=<br />
-o smtpd_recipient_restrictions=permit_mynetworks,reject<br />
-o mynetworks_style=host<br />
-o smtpd_authorized_xforward_hosts=127.0.0.0/8<br />
* postfix reload<br />
* Send and email into a local virtual domain - it should have the ''X-Virus-Scanned: ClamAV using ClamSMTP'' header.<br />
<br />
=== Relay for Authenticated Users ===<br />
<br />
As configured above, the mail server accepts email from the Internet, but it does not relay email. If it is a perimeter exchanger for a protected network, then you can add the protected networks to the ''mynetworks'' configuration line in /etc/postfix/main.cf<br />
<br />
This configuration change allows ''remote'' users to authenticate against the mail server and relay through it. The rules for relaying are:<br />
* Only authenticated users can relay<br />
* Authentication Credentials must be encrypted with TLS or SSL<br />
* Allow Submission and SMTPS ports for relaying (many consumer networks block port 25 - SMTP by default)<br />
The process uses the dovecot authentication mechanism (used with IMAPS) to authenticate users before they are allowed to relay through postfix.<br />
<br />
<br />
* Edit /etc/dovecot/dovecot.conf and add teh following inside the ''auth default'' stanza:<br />
# this is for postfix SASL (authenticated users can relay through us)<br />
socket listen {<br />
client {<br />
path = /var/spool/postfix/private/dovecot-auth.sock<br />
mode = 0660<br />
user = postfix<br />
group = postfix<br />
}<br />
}<br />
}<br />
* Restart dovecot<br />
/etc/init.d/dovecot restart<br />
* Edit /etc/postfix/main.cf and add:<br />
# TLS Stuff -- since we allow SASL with tls *only*, we have to set up TLS first <br />
<br />
smtpd_tls_cert_file = /etc/lighttpd/server-bundle.pem<br />
smtpd_tls_key_file = /etc/lighttpd/server-bundle.pem<br />
smtpd_tls_CAfile = /etc/lighttpd/ca-crt.pem<br />
# If tls_security_level is set to "encrypt", then SMTP rejects <br />
# unencrypted email (e.g. normal mail) which is bad.<br />
# By setting it to "may" you get TLS encrypted mail from google, slashdot, and other <br />
# interesting places. Check your logs to see who<br />
smtpd_tls_security_level = may<br />
# Log info about the negotiated encryption levels<br />
smtpd_tls_received_header = yes<br />
smtpd_tls_loglevel = 1<br />
<br />
# SASL - this allows senders to authenticiate themselves<br />
# This along with "permit_sasl_authenticated" in smtpd_recipient_restrictions allows relaying<br />
smtpd_sasl_type = dovecot<br />
smtpd_sasl_path = private/dovecot-auth.sock<br />
smtpd_sasl_auth_enable = yes<br />
smtpd_sasl_authenticated_header = yes<br />
smtpd_tls_auth_only = yes<br />
* Edit /etc/postfix/master.cf and enable the submission and smtps transports. They are probably already at the top of your master.cf file, just commented out:<br />
submission inet n - n - - smtpd<br />
-o smtpd_tls_security_level=encrypt<br />
-o smtpd_sasl_auth_enable=yes<br />
-o smtpd_client_restrictions=permit_sasl_authenticated,reject<br />
-o milter_macro_daemon_name=ORIGINATING<br />
smtps inet n - n - - smtpd<br />
-o smtpd_tls_security_level=encrypt<br />
-o smtpd_tls_wrappermode=yes<br />
-o smtpd_sasl_auth_enable=yes<br />
-o smtpd_client_restrictions=permit_sasl_authenticated,reject<br />
-o milter_macro_daemon_name=ORIGINATING<br />
*Verfiy submission and smtps are defined in /etc/services<br />
grep "submission\|ssmtp" /etc/services<br />
submission 587/tcp # mail message submission<br />
submission 587/udp<br />
smtps 465/tcp ssmtp # smtp protocol over TLS/SSL<br />
smtps 465/udp ssmtp<br />
* Restart postfix<br />
postfix reload<br />
<br />
At this point, you should be able to set up a mail client to relay through the server with TLS (port 587) or SSL (port 465) Note that "plain" authentication is used because the underlying link is encrypted. For example, in Thunderbird leave "secure authentication" unchecked, and choose STARTTLS (or TLS) for the connection security.<br />
<br />
=== Mailbox Quotas ===<br />
<br />
In the default configuration, PostfixAdmin knows about quotas, but they are not enforced. Documentation on the web mentions the [http://vda.sourceforge.net vda patch to postfix] to enforce quotas. The only bad thing... its a ''patch''. Postfix and Dovecot are both conservative systems, so if the patch isn't in the upstream source, we'll assume there's a good reason. There is a way of using quotas without patches - and it involves using dovecot's [http://wiki.dovecot.org/LDA deliver] lda for local delivery.<br />
<br />
Note: As of Jan 2010, the documention is confusing, with multiple versions of dovecot, PostfixAdmin, and Mysql referenced. These instructions apply to:<br />
* Postgresql 8.4.2 <br />
* PostfixAdmin 2.3 <br />
* Dovecot 1.2.11<br />
* Postfix 2.6.5<br />
<br />
Presumably later versions will work the same, but if not, please update the documentation and versions above.<br />
<br />
* Update /etc/dovecot/dovecot.conf (old lines shown commented out):<br />
<br />
<pre><br />
# old postfix <br />
# userdb static {<br />
# args = uid=1006 gid=1006 home=/var/mail/domains/%d/%n<br />
# }<br />
<br />
# new quota support:<br />
userdb prefetch {<br />
}<br />
<br />
userdb sql {<br />
args = /etc/dovecot/dovecot-sql.conf<br />
}<br />
<br />
socket listen {<br />
client {<br />
path = /var/spool/postfix/private/dovecot-auth.sock<br />
mode = 0660<br />
user = postfix<br />
group = postfix<br />
}<br />
# These lines below are for the deliver lda<br />
master {<br />
path = /var/run/dovecot/auth-master<br />
mode = 0660<br />
user = vmail<br />
group = vmail<br />
}<br />
}<br />
}<br />
<br />
protocol imap { <br />
mail_plugins = quota imap_quota <br />
} <br />
<br />
protocol pop3 { <br />
mail_plugins = quota <br />
} <br />
<br />
dict { <br />
quotadict = pgsql:/etc/dovecot/dovecot-dict-quota.conf <br />
} <br />
<br />
plugin { <br />
quota = dict:user::proxy::quotadict <br />
} <br />
<br />
protocol lda { <br />
postmaster_address = postmaster@host.example.com<br />
mail_plugins = quota <br />
auth_socket_path = /var/run/dovecot/auth-master<br />
sendmail_path = /usr/sbin/sendmail<br />
} <br />
</pre><br />
<br />
You should already have a <tt>socket-> listen-> client</tt> section, but it is listed above to show where it goes in relationship to the <tt>socket -> listen -> master</tt> section<br />
<br />
<br />
* edit <tt>/etc/dovecot/dovecot-sql.conf</tt> and replace the user and password queries with the following (you may not have a user_query yet - add it):<br />
<br />
password_query = select username as user, password, 1006 as userdb_uid, 1006 as userdb_gid, '*:bytes=' || quota as userdb_quota_rule from mailbox where local_part = '%n' and domain = '%d'<br />
user_query = select '/var/mail/domains/' || maildir as home, 1006 as uid, 1006 as gid, '*:bytes=' || quota as quota_rule from mailbox where local_part = '%n' and domain ='%d'<br />
<br />
<br />
* create <tt>/etc/dovecot/dovecot-dict-quota.conf</tt><br />
connect = host=localhost dbname=postfix user=postfix password=********<br />
<br />
map {<br />
pattern = priv/quota/storage<br />
table = quota2<br />
username_field =username<br />
value_field = bytes<br />
}<br />
<br />
map {<br />
pattern= priv/quota/messages<br />
table = quota2<br />
username_field = username<br />
value_field = messages<br />
}<br />
<br />
Again, change the password above to your postfix user password, and protect the file from prying eyes:<br />
chown root:root /etc/dovecot/dovecot-dict-quota.conf<br />
chmod 600 /etc/dovecot/dovecot-dict-quota.conf<br />
<br />
Side note: [http://wiki.dovecot.org/Quota/Dict The Dovecot Quota Documentation] mentions the need for a trigger with pgsql. This was created in the PostfixAdmin install, which is why you instantiated the pgsql language when creating the database. If not, you will need to create the trigger, to reference the quota2 table, not the quota table mentioned in the dovecot docs.<br />
<br />
<br />
* create a new transport for the dovecot lda. Add the following to /etc/postfix/master.cf:<br />
# The dovecot deliver lda<br />
dovecot unix - n n - - pipe<br />
flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${user}@${nexthop}<br />
<br />
* Edit the /etc/postfix/main.cf. Replace <br />
virtual_transport = virtual <br />
with<br />
virtual_transport = dovecot<br />
dovecot_destination_recipient_limit = 1<br />
<br />
Change permissions on the /var/log/dovecot* log files, so that the vmail user can write to them:<br />
<br />
chown vmail:vmail /var/log/dovecot*<br />
<br />
Restart Postfix and Dovecot:<br />
<br />
/etc/init.d/postfix restart<br />
/etc/init.d/dovecot restart<br />
<br />
'''TODO''' This will cause over-quota emails to bounce. Which could be a source of backscatter. We need a way of checking quota limits after RBL checking but before the message is accepted in the queue.<br />
<br />
=== WebMail (RoundCube) ===<br />
<br />
[http://roundcube.net/ RoundCube] is an "ajax /Web2.0" web-mail client. These instructions are for the Alpine Linux 1.10 repository <br />
<br />
* Add the package and related php modules:<br />
apk add roundcubemail php-xml php-openssl php-mcrypt php-gd php-iconv<br />
<br />
* link the roundcube application back into the docroot<br />
ln -s /usr/share/webapps/roundcube /var/www/domains/host.example.com/www/roundcube<br />
<br />
* follow the instructions in /usr/share/webapps/roundcube/INSTALL:<br />
cd /usr/share/webapps/roundcube<br />
chown -R lighttpd:lighttpd temp logs<br />
<br />
su postgres<br />
createuser roundcube<br />
Shall the new role be a superuser? (y/n) n<br />
Shall the new role be allowed to create databases? (y/n) n<br />
Shall the new role be allowed to create more new roles? (y/n) y<br />
createdb -O roundcube -E UNICODE -T template0 roundcubemail<br />
psql roundcubemail<br />
roundcubemail=# ALTER USER roundcube WITH PASSWORD 'the_new_password';<br />
roundcubemail=# \c - roundcube<br />
roundcubemail=> \i /usr/share/webapps/roundcube/SQL/postgres.initial.sql<br />
roundcubemail=> \q<br />
exit<br />
<br />
* edit /etc/php/php.ini and set date.timezone to your local timezone, or to UTC<br />
<br />
* restart lighttpd to verify the new php libraries are used<br />
/etc/init.d/lighttpd restart<br />
<br />
* Point your browser to http://host.example.com/roundcube/installer<br />
* Start installation<br />
<br />
For the specific configuration parameters in the install step:<br />
<br />
{| class="wikitable"<br />
!Property<br />
!Setting<br />
|-<br />
| ''enable_spellcheck'' || disabled <br />
|-<br />
| ''identities_level'' || one identity with possibility to edit all params but not email address <br />
|-<br />
| ''log driver'' || syslog <br />
|-<br />
| ''sylog_id'' || roundcube <br />
|-<br />
| ''syslog_facility'' || mailsubsystem <br />
|-<br />
| ''db_dnsw'' || pgsql properties, as described above <br />
|-<br />
| ''imap_host'' || 127.0.0.1 <br />
|-<br />
| ''auto_create_user'' || enabled <br />
|-<br />
| ''smtp_server'' || 127.0.0.1<br />
|-<br />
| ''smtp_port'' || 25<br />
|-<br />
| ''smtp_user/smtp_pass'' || enable ''Use Current IMAP username and password for SMTP authentication''<br />
|-<br />
| ''smtp_log'' || enable (optional, but gives additional log record)<br />
|}<br />
<br />
The other items can be left at default settings, or adjusted if desired.<br />
<br />
* Follow the instructions in step 3 of the install to copy the files to the server<br />
* You should now be able to get to roundcube at http://host.example.com/roundcube<br />
<br />
<br />
<br />
<br />
After its working, the INSTALL file recommends removing the install directory. If you want to keep the installer around later, you can simply change the ownership and permissions. So do '''one''' of the following:<br />
cd /usr/share/webapps/roundcube<br />
rm -rf LICENSE UPGRADING INSTALL README CHANGELOG SQL installer<br />
or<br />
cd /usr/share/webapps/roundcube<br />
chown -R root:root LICENSE UPGRADING INSTALL README CHANGELOG SQL installer<br />
chmod -R 600 LICENSE UPGRADING INSTALL README CHANGELOG SQL <br />
chmod 700 SQL installer<br />
<br />
==== Enable Plug-ins ====<br />
<br />
RoundCube has various useful plug-ins, which could be found in ''/usr/share/webapps/roundcube/plugins'' directory. For example you may want to enable ''password'' plug-in to let users change their passwords directly from RoundCube using an extra Password Tab added to User Settings.<br />
<br />
* Grant limited permissions for ''roundcube'' database role <br />
psql -U postgres postfix<br />
postfix=# GRANT UPDATE (password,modified) ON mailbox TO roundcube;<br />
postfix=# GRANT SELECT (username) ON mailbox TO roundcube;<br />
postfix=# GRANT INSERT ON log TO roundcube;<br />
postfix=# \q<br />
<br />
* Setup ''password'' plug-in parameters in ''/usr/share/webapps/roundcube/plugins/password/config.inc.php''<br />
mv /usr/share/webapps/roundcube/plugins/password/config.inc.php.dist /usr/share/webapps/roundcube/plugins/password/config.inc.php<br />
vi /usr/share/webapps/roundcube/plugins/password/config.inc.php<br />
<br />
<pre><br />
$rcmail_config['password_minimum_length'] = 7;<br />
$rcmail_config['password_require_nonalpha'] = true;<br />
...<br />
$rcmail_config['password_db_dsn'] = 'pgsql://roundcube:<roundcube_password>@localhost/postfix';<br />
...<br />
$rcmail_config['password_query'] = "UPDATE mailbox set password = %c, modified = NOW() where username = %u; INSERT INTO log (timestamp,username,domain,action,data) VALUES (NOW(),%u || ' (' || %h || ')',%d,'edit_password',%u)";<br />
</pre><br />
<br />
* Enable ''password'' plug-in<br />
vi /usr/share/webapps/roundcube/config/main.inc.php<br />
<br />
<pre><br />
...<br />
$rcmail_config['plugins'] = array('password');<br />
</pre><br />
<br />
=== OpenLDAP based Address Book ===<br />
<br />
This OpenLDAP configuration uses the SQL backend, which represents information stored in PostgreSQL as an LDAP subtree for Address Book functionality for email lookups, user authentication or even <br />
replication account information between sites. This procedure uses some metainformation to translate LDAP queries to SQL queries, leaving relational schema untouched, which allows SQL and LDAP <br />
applications to inter-operate without replication, and exchange data as needed. The SQL backend uses UnixODBC to connect to PostgresSQL. <br />
<br />
* Install OpenLDAP and ODBC<br />
<br />
<pre><br />
apk add openldap libldap openldap-back-sql php-ldap unixodbc psqlodbc ca-certificates<br />
</pre><br />
<br />
'''Note''': The psqlodbc package is currently unavailable<br />
<br />
* Update "postfix" database (it will add 'id' columns to mailbox and domain tables, also will create tables and views to represent LDAP metainformation)<br />
<br />
'''Note''': These instructions are for example domain example.com. So make sure you replaced all entries of 'example' and 'com' according to your domain name parts.<br />
<br />
Put the following into a new file called '''script''':<br />
<br />
<pre><br />
ALTER TABLE domain ADD COLUMN id SERIAL; <br />
ALTER TABLE mailbox ADD COLUMN id SERIAL; <br />
<br />
CREATE TABLE ldap_entry_objclasses (<br />
entry_id integer NOT NULL,<br />
oc_name character varying(64)<br />
);<br />
<br />
CREATE TABLE ldap_oc_mappings (<br />
name character varying(64) NOT NULL,<br />
keytbl character varying(64) NOT NULL,<br />
keycol character varying(64) NOT NULL,<br />
create_proc character varying(255),<br />
delete_proc character varying(255),<br />
expect_return integer NOT NULL<br />
);<br />
<br />
ALTER TABLE ldap_oc_mappings ADD COLUMN id SERIAL;<br />
ALTER TABLE ldap_oc_mappings ADD PRIMARY KEY (id);<br />
<br />
CREATE TABLE ldap_attr_mappings (<br />
oc_map_id integer NOT NULL REFERENCES ldap_oc_mappings(id),<br />
name character varying(255) NOT NULL,<br />
sel_expr character varying(255) NOT NULL,<br />
sel_expr_u character varying(255),<br />
from_tbls character varying(255) NOT NULL,<br />
join_where character varying(255),<br />
add_proc character varying(255),<br />
delete_proc character varying(255),<br />
param_order integer NOT NULL,<br />
expect_return integer NOT NULL<br />
);<br />
<br />
ALTER TABLE ldap_attr_mappings ADD COLUMN id SERIAL;<br />
ALTER TABLE ldap_attr_mappings ADD PRIMARY KEY (id);<br />
<br />
CREATE VIEW ldap_dcs AS<br />
((SELECT (domain.id + 100000) AS id,<br />
('dc='::text || replace((domain.domain)::text, '.'::text, ',dc='::text)) AS dn,<br />
1 AS oc_map_id,<br />
100000 AS parent,<br />
0 AS keyval,<br />
domain.domain<br />
FROM domain<br />
WHERE domain.domain <> 'ALL')<br />
UNION<br />
(SELECT 100000 AS id,<br />
('dc=' || regexp_replace((domain.domain)::text, '.*\\.', ''::text)) AS dn,<br />
1 AS oc_map_id,<br />
0 AS parent,<br />
0 AS keyval,<br />
(regexp_replace((domain.domain)::text, '.*\\.', ''::text)) AS domain<br />
FROM domain<br />
WHERE domain.domain <> 'ALL'<br />
LIMIT 1));<br />
<br />
CREATE VIEW ldap_entries AS<br />
SELECT mailbox.id,<br />
((('cn='::text || initcap(replace(split_part((mailbox.username)::text, '@'::text, 1), '.'::text, ' '::text))) || ',dc='::text) ||<br />
replace(regexp_replace((mailbox.username)::text, '.*@', ''::text), '.'::text, ',dc='::text)) AS dn,<br />
1 AS oc_map_id,<br />
(SELECT ldap_dcs.id<br />
FROM ldap_dcs<br />
WHERE ((ldap_dcs.domain)::text = (mailbox.domain)::text)) AS parent,<br />
mailbox.id AS keyval<br />
FROM mailbox<br />
UNION<br />
SELECT ldap_dcs.id,<br />
ldap_dcs.dn,<br />
ldap_dcs.oc_map_id,<br />
ldap_dcs.parent,<br />
ldap_dcs.keyval<br />
FROM ldap_dcs;<br />
</pre><br />
<br />
Finally, execute the commands in the file with:<br />
cat script | psql -U postfix postfix<br />
rm script<br />
<br />
* Fill out LDAP tables according to following example (make sure to separate values with TABs):<br />
<br />
Put the following into a new file called '''script''':<br />
<br />
<pre><br />
COPY ldap_oc_mappings (id, name, keytbl, keycol, create_proc, delete_proc, expect_return) FROM stdin;<br />
1 exampleBox mailbox id \N \N 1<br />
\.<br />
COPY ldap_attr_mappings (id, oc_map_id, name, sel_expr, sel_expr_u, from_tbls, join_where, add_proc, delete_proc, param_order, expect_return) FROM stdin;<br />
1 1 displayName mailbox.name \N mailbox \N \N \N 3 0<br />
2 1 mail mailbox.username \N mailbox \N \N \N 3 0<br />
3 1 cn mailbox.name \N mailbox \N \N \N 3 0<br />
4 1 userPassword '{CRYPT}'||mailbox.password \N mailbox \N \N \N 3 0<br />
\.<br />
</pre><br />
<br />
Finally, execute the commands in the file with:<br />
cat script | psql -U postfix postfix<br />
rm script<br />
<br />
* Check that "ldap_dcs" view looks something like this:<br />
<br />
<pre><br />
echo 'select * from ldap_dcs' | psql -U postgres postfix<br />
</pre><br />
<br />
<pre><br />
id | dn | oc_map_id | parent | keyval | domain <br />
--------+-----------------------------+-----------+--------+--------+--------------------<br />
100000 | dc=com | 1 | 0 | 0 | com<br />
100001 | dc=example,dc=com | 1 | 100000 | 0 | example.com<br />
</pre><br />
<br />
* Check that "ldap_entries" view looks something like this:<br />
<br />
<pre><br />
echo 'select * from ldap_entries' | psql -U postgres postfix<br />
</pre><br />
<br />
<pre><br />
id | dn | oc_map_id | parent | keyval <br />
--------+-------------------------------------------------------+-----------+--------+--------<br />
1 | cn=address1,dc=example,dc=com | 1 | 100001 | 1<br />
...<br />
123 | cn=address123,dc=example,dc=com | 1 | 100001 | 1<br />
100000 | dc=com | 1 | 0 | 0<br />
100001 | dc=example,dc=com | 1 | 100000 | 0<br />
</pre><br />
<br />
* Configure ODBC parameters<br />
<br />
Edit /etc/odbc.ini:<br />
<br />
<pre><br />
[PostgreSQL]<br />
Description = Connection to Postgres<br />
Driver = PostgreSQL<br />
Trace = Yes<br />
TraceFile = sql.log<br />
Database = postfix<br />
Servername = 127.0.0.1<br />
UserName =<br />
Password =<br />
Port = 5432<br />
Protocol = 6.4<br />
ReadOnly = No<br />
RowVersining = No<br />
ShowSystemTables = No<br />
ShowOidColumn = No<br />
FakeOidIndex = No<br />
ConnSettings =<br />
</pre><br />
<br />
Edit /etc/odbcinst.ini:<br />
<br />
<pre><br />
[PostgreSQL]<br />
Description = PostgreSQL driver for Linux<br />
Driver = /usr/lib/psqlodbcw.so<br />
Setup = /usr/lib/libodbcpsqlS.so<br />
FileUsage = 1<br />
</pre><br />
<br />
* Test ODBC connection<br />
<br />
<pre><br />
echo "select * from domain;" | isql PostgreSQL postgres<br />
</pre><br />
<br />
* Provide permission to certificate for LDAP server<br />
<br />
<pre><br />
chown ldap /etc/lighttpd/server-bundle.pem<br />
</pre><br />
<br />
* Edit LDAP schema<br />
<br />
Edit /etc/openldap/schema/example.com.schema:<br />
<br />
<pre><br />
attributetype ( 0.9.2342.19200300.100.1.3<br />
NAME ( 'mail' 'rfc822Mailbox' )<br />
DESC 'RFC1274: RFC822 Mailbox'<br />
EQUALITY caseIgnoreIA5Match<br />
SUBSTR caseIgnoreIA5SubstringsMatch<br />
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )<br />
<br />
attributetype ( 2.16.840.1.113730.3.1.241<br />
NAME 'displayName'<br />
DESC 'RFC2798: preferred name to be used when displaying entries'<br />
EQUALITY caseIgnoreMatch<br />
SUBSTR caseIgnoreSubstringsMatch<br />
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15<br />
SINGLE-VALUE )<br />
<br />
objectclass ( 2.16.840.1.113730.3.2.2<br />
NAME 'exampleBox'<br />
DESC 'example.com mailbox'<br />
MUST ( displayName $ mail $ userPassword )<br />
)<br />
<br />
# RFC 1274 + RFC 2247<br />
attributetype ( 0.9.2342.19200300.100.1.25<br />
NAME ( 'dc' 'domainComponent' )<br />
DESC 'RFC1274/2247: domain component'<br />
EQUALITY caseIgnoreIA5Match<br />
SUBSTR caseIgnoreIA5SubstringsMatch<br />
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )<br />
<br />
attributetype ( 2.5.4.46 NAME 'dnQualifier'<br />
DESC 'RFC2256: DN qualifier'<br />
EQUALITY caseIgnoreMatch<br />
ORDERING caseIgnoreOrderingMatch<br />
SUBSTR caseIgnoreSubstringsMatch<br />
SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 )<br />
</pre><br />
<br />
* Configure LDAP server<br />
<br />
Edit /etc/openldap/slapd.conf:<br />
<br />
<pre><br />
include /etc/openldap/schema/example.com.schema<br />
pidfile /var/run/openldap/slapd.pid<br />
argsfile /var/run/openldap/slapd.args<br />
<br />
TLSCipherSuite HIGH<br />
TLSCACertificateFile /etc/lighttpd/ca-crt.pem<br />
TLSCertificateFile /etc/lighttpd/server-bundle.pem<br />
TLSCertificateKeyFile /etc/lighttpd/server-bundle.pem<br />
TLSVerifyClient never <br />
<br />
# This is needed for proper representation of MD5-CRYPT format stored in database<br />
# see more details in http://strugglers.net/~andy/blog/2010/01/23/openldap-and-md5crypt/<br />
password-hash {CRYPT}<br />
password-crypt-salt-format "$1$%.8s"<br />
<br />
loglevel stats<br />
moduleload /usr/lib/openldap/back_sql.so<br />
sizelimit 3000<br />
<br />
database sql<br />
<br />
dbname PostgreSQL<br />
dbuser postfix<br />
dbpasswd *****<br />
<br />
suffix "dc=example,dc=com"<br />
<br />
upper_func "upper"<br />
strcast_func "text"<br />
concat_pattern "?||?"<br />
has_ldapinfo_dn_ru no<br />
lastmod off<br />
<br />
access to attrs=userPassword by * auth<br />
<br />
access to * by peername.ip=127.0.0.1 read<br />
# by peername.ip=<IP>%<netmask> read<br />
# by peername.ip=<IP> read<br />
by users read<br />
</pre><br />
<br />
* Set permissions for slapd.conf<br />
<br />
<pre><br />
chown ldap:ldap /etc/openldap/slapd.conf<br />
</pre><br />
<br />
* Configure startup parameters to make sure that LDAP server start AFTER PostgreSQL and listens on localhost with clear text and public IP with SSL<br />
<br />
Edit /etc/conf.d/slapd:<br />
<br />
<pre><br />
rc_need="postgresql" <br />
OPTS="-h 'ldaps:// ldap://127.0.0.1'"<br />
</pre><br />
<br />
* Start LDAP server<br />
<br />
<pre><br />
rc-update add slapd default<br />
/etc/init.d/slapd start<br />
</pre><br />
<br />
* Configure LDAP client utilities<br />
<br />
Edit /etc/openldap/ldap.conf<br />
<br />
<pre><br />
BASE dc=example,dc=com<br />
URI ldaps://host.example.com<br />
<br />
TLS_CACERT /etc/lighttpd/ca-crt.pem<br />
TLS_CERT /etc/lighttpd/server-bundle.pem<br />
TLS_KEY /etc/lighttpd/server-bundle.pem<br />
</pre><br />
<br />
* Test LDAP server<br />
<br />
<pre><br />
ldapsearch -z 3<br />
ldapsearch -z 3 -x -W -D cn=admin,dc=example,dc=com<br />
ldapsearch -z 3 -x -W -D cn=address1,dc=example,dc=com<br />
</pre><br />
<br />
* Configure RoundCube webmail for email lookups<br />
<br />
In order to enable php-ldap support you need to restart lighttpd server<br />
<br />
/etc/init.d/lighttpd restart<br />
<br />
Edit /usr/share/webapps/roundcube/config/main.inc.php:<br />
<br />
<pre><br />
$rcmail_config['ldap_debug'] = false;<br />
...<br />
$rcmail_config['address_book_type'] = 'sql';<br />
<br />
$rcmail_config['ldap_public']['example.com'] = array(<br />
'name' => 'example.com',<br />
'hosts' => array('127.0.0.1'),<br />
'port' => 389,<br />
'use_tls' => false,<br />
'user_specific' => false,<br />
'base_dn' => 'dc=example,dc=com',<br />
'bind_dn' => '',<br />
'bind_pass' => '',<br />
'writable' => false,<br />
'LDAP_Object_Classes' => array("top", "exampleBox"),<br />
'required_fields' => array("cn", "sn", "mail"),<br />
'LDAP_rdn' => 'mail',<br />
'ldap_version' => 3,<br />
'search_fields' => array('mail', 'cn', 'sn', 'givenName'),<br />
'name_field' => 'cn',<br />
'email_field' => 'mail',<br />
'surname_field' => 'sn',<br />
'firstname_field' => 'gn',<br />
'sort' => 'cn',<br />
'scope' => 'sub',<br />
'filter' => '(objectClass=*)', // Construct here any filter you need<br />
'fuzzy_search' => true);<br />
<br />
$rcmail_config['autocomplete_addressbooks'] = array('sql','example.com');<br />
</pre><br />
<br />
* Fix PostfixAdmin to work with the new table definition<br />
<br />
Edit /var/www/domains/example.com/www/postfixadmin/list-domain.php. Replace the line:<br />
<pre><br />
SELECT domain.* , COUNT( DISTINCT mailbox.username ) AS mailbox_count<br />
</pre><br />
With the lines:<br />
<pre><br />
SELECT domain.domain, domain.description, domain.aliases, domain.mailboxes,<br />
domain.maxquota, domain.quota, domain.transport, domain.backupmx, domain.created,<br />
domain.modified, domain.active, COUNT( DISTINCT mailbox.username ) AS mailbox_count<br />
</pre><br />
<br />
== log rotation ==<br />
<br />
Ensure the busybox cron service is started and is configured to auto-start:<br />
<br />
/etc/init.d/cron start<br />
rc-update add cron default<br />
<br />
Add log rotate:<br />
<br />
apk add logrotate<br />
<br />
Edit ''/etc/logrotate.conf'' as desired, but the defaults should be sufficient for most people.<br />
<br />
== Optional: Configure Web Server Virtual Domains ==<br />
<br />
'''Note:''' These steps can be done ''in addition to'' the default lighttpd configuration above, which allows you to access the ACF, PostfixAdmin and Roundcube interfaces as subfolders of one web service.<br />
<br />
'''Note:''' If you provide SSL access for multiple domain site you may need to follow http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs:SSL#SSL-on-multiple-domains in order to provide multi-domain certificates. If you would like to redirect hosts to their secure equivalents use the following instructions http://redmine.lighttpd.net/projects/lighttpd/wiki/HowToRedirectHttpToHttps.<br />
<br />
This server hosts three separate web applications, and these can be handled as three ''different'' virtual domains on the same web server. They will be distinguished by their DNS names, so you can choose domains for the three separate services (or at least the ones you want to publish):<br />
<br />
* ACF - Alpine Configuration Framework for managing the server<br />
* PostfixAdmin - for managing the postfix installation<br />
* RoundCube - for accessing individual mailboxes<br />
<br />
Choose three different domains (from here on known as ACF_DOMAIN, POSTFIXADMIN_DOMAIN, and ROUNDCUBE_DOMAIN) and configure DNS for all three to point to the IP address of your host. These should be DNS '''A''' records.<br />
<br />
Then, configure lighttpd to handle the three separate domains by editing /etc/lighttpd/lighttpd.conf:<br />
<br />
<pre><br />
$HTTP["host"] == "ACF_DOMAIN" {<br />
simple-vhost.server-root = "/var/www/domains/"<br />
simple-vhost.default-host = "/ACF_DOMAIN/"<br />
simple-vhost.document-root = "www/"<br />
}<br />
<br />
$HTTP["host"] == "POSTFIXADMIN_DOMAIN" {<br />
simple-vhost.server-root = "/var/www/domains/"<br />
simple-vhost.default-host = "/POSTFIXADMIN_DOMAIN/"<br />
simple-vhost.document-root = "www/"<br />
}<br />
<br />
$HTTP["host"] == "ROUNDCUBE_DOMAIN" {<br />
simple-vhost.server-root = "/var/www/domains/"<br />
simple-vhost.default-host = "/ROUNDCUBE_DOMAIN/"<br />
simple-vhost.document-root = "www/"<br />
}<br />
</pre><br />
<br />
And, then link the appropriate www directories.<br />
<pre><br />
mkdir -p /var/www/domains/ACF_DOMAIN<br />
ln -s /usr/share/acf/www /var/www/domains/ACF_DOMAIN/www<br />
<br />
mkdir -p /var/www/domains/POSTFIXADMIN_DOMAIN<br />
ln -s /var/www/domains/host.example.com/www/postfixadmin /var/www/domains/POSTFIXADMIN_DOMAIN/www<br />
<br />
mkdir -p /var/www/domains/ROUNDCUBE_DOMAIN<br />
ln -s /usr/share/webapps/roundcube /var/www/domains/ROUNDCUBE_DOMAIN/www<br />
</pre></div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Upgrading_Alpine_-_v1.9.x&diff=3732Upgrading Alpine - v1.9.x2010-05-03T14:04:50Z<p>Aalatchm: /* Download and verify new release */ correction. minor</p>
<hr />
<div>This document covers upgrading from a previous version of Alpine 1.9 (or 1.10) to newer versions of 1.9 (or 1.10). Thanks to many improvements in Alpine 1.9, it is possible to easily upgrade in most scenarios.<br />
<br />
All examples/instructions/actions mentioned in this document should be executed on the box that you are planning to upgrade (unless you are instructed otherwise).<br />
<br />
== Upgrading an Alpine Linux Hard-disk installation ==<br />
<br />
When Alpine is installed to hard drive, upgrading the installation is simple.<br />
<br />
{{Using_Internet_Repositories_for_apk-tools}}<br />
<br />
Ensure you have the latest available version of the Alpine Package Manager first before upgrading anything else:<br />
apk add -u apk-tools<br />
<br />
Finally, upgrade all remaining packages, including the kernel if applicable:<br />
apk upgrade<br />
<br />
== Upgrading Separate Boot Media ==<br />
<br />
You may have an installation where the boot media being used (such as a CD, for example) is separate from the media used to store the configuration information. In this case, simply download the latest ISO, and replace the boot media contents with the contents of the latest ISO. If you are booting from a CD, this would simply mean replacing the CD with a CD made from the new image and rebooting the Alpine box. <br />
<br />
== Upgrading Alpine on CF/USB ==<br />
<br />
Your installation may consist of Alpine running on Compact Flash or USB media. In most cases, it should be sufficient to upgrade most packages using the '''Alpine Hard-disk Installation''' upgrade procedures described above. However, for new packages to survive after a reboot, you should enable [[How_to_enable_APK_caching|APK caching]].<br />
<br />
{{Warning|As the newer version of alpine may include kernel upgrades, simply pointing the Alpine Package Manager to an Internet-based repository and running ''apk upgrade'' will not be enough, as kernel components are not upgraded when Alpine is run from memory.}}<br />
<br />
{{Upgrading_Alpine_environmentvars}}<br />
<br />
=== Upgrade Step-by-Step ===<br />
<br />
Start by checking that you have enough space on your media.<BR><br />
You need at least 400MB available space.<br />
df -h | grep "Filesystem\|$LBU_MEDIA"<br />
<br />
==== Download and verify new release ====<br />
<br />
Start downloading a new '.iso' and a '.sha1' file <br />
cd /media/$LBU_MEDIA<br />
wget -c {{Latest_1.10_alpine_iso-mirror}}{{Latest_1.10_alpine_iso-filename}}<br />
wget http://dev.alpinelinux.org/alpine/v1.10/releases/{{Latest_1.10_alpine_iso-filename}}.sha1<br />
<br />
Check integrity of the downloaded files ''(it might take some time)''<br />
sha1sum -c {{Latest_1.10_alpine_iso-filename}}.sha1<br />
''The output of the above command should say 'OK'.<BR>''<br />
''If says 'FAILED', delete the iso file and download it again.''<br />
<br />
==== Copy the new release ====<br />
<br />
Mount the ISO.<br />
<br />
mount -t iso9660 {{Latest_1.10_alpine_iso-filename}} /mnt<br />
<br />
Back up files that you have modified. For example, you might have modified ''syslinux.cfg'' to show console output on a serial port.<BR><br />
<br />
cp /media/$LBU_MEDIA/syslinux.cfg /media/$LBU_MEDIA/syslinux.cfg.my<br />
<br />
Install the '''rsync''' package if necessary, and copy the files:<br />
<br />
cd /mnt<br />
apk add rsync<br />
rsync --delete -rltv .alpine-release * /media/$LBU_MEDIA/ <br />
<br />
Restore your backed up files ''(in case you had any)''<br />
<br />
mv -f /media/$LBU_MEDIA/syslinux.cfg.my /media/$LBU_MEDIA/syslinux.cfg<br />
<br />
Make sure that all files are permanently saved in right place <br />
<br />
sync<br />
<br />
==== Clean up ====<br />
Clean up the downloaded/unpacked files<br />
cd ..<br />
umount /mnt<br />
rm /media/$LBU_MEDIA/{{Latest_1.10_alpine_iso-filename}}<br />
rm /media/$LBU_MEDIA/{{Latest_1.10_alpine_iso-filename}}.sha1<br />
<br />
=== Save changes ===<br />
Now that all upgrades are done, we should save our settings to our media (which you hopefully have backed up prior to doing this upgrade).<br />
lbu ci<br />
<br />
=== Load new kernel ===<br />
In most cases you will need to reboot Alpine (especially if there are changes in the kernel):<br />
reboot<br />
{{Note|If you know what you are doing, you might not need to reboot. But make sure that all services affected by the upgrade are restarted.}}<br />
<br />
=== Update remaining packages from Web repository ===<br />
<br />
* Check that /etc/apk/repositories reflects the current version, for example, for 1.10 it could say:<br />
http://dl-3.alpinelinux.org/alpine/v1.10/packages/main<br />
* Upgrade packages from Web.<br />
apk update<br />
apk add -u apk-tools<br />
apk upgrade -U</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Upgrading_Alpine_-_v1.9.x&diff=3731Upgrading Alpine - v1.9.x2010-05-03T14:03:51Z<p>Aalatchm: comment removed</p>
<hr />
<div>This document covers upgrading from a previous version of Alpine 1.9 (or 1.10) to newer versions of 1.9 (or 1.10). Thanks to many improvements in Alpine 1.9, it is possible to easily upgrade in most scenarios.<br />
<br />
All examples/instructions/actions mentioned in this document should be executed on the box that you are planning to upgrade (unless you are instructed otherwise).<br />
<br />
== Upgrading an Alpine Linux Hard-disk installation ==<br />
<br />
When Alpine is installed to hard drive, upgrading the installation is simple.<br />
<br />
{{Using_Internet_Repositories_for_apk-tools}}<br />
<br />
Ensure you have the latest available version of the Alpine Package Manager first before upgrading anything else:<br />
apk add -u apk-tools<br />
<br />
Finally, upgrade all remaining packages, including the kernel if applicable:<br />
apk upgrade<br />
<br />
== Upgrading Separate Boot Media ==<br />
<br />
You may have an installation where the boot media being used (such as a CD, for example) is separate from the media used to store the configuration information. In this case, simply download the latest ISO, and replace the boot media contents with the contents of the latest ISO. If you are booting from a CD, this would simply mean replacing the CD with a CD made from the new image and rebooting the Alpine box. <br />
<br />
== Upgrading Alpine on CF/USB ==<br />
<br />
Your installation may consist of Alpine running on Compact Flash or USB media. In most cases, it should be sufficient to upgrade most packages using the '''Alpine Hard-disk Installation''' upgrade procedures described above. However, for new packages to survive after a reboot, you should enable [[How_to_enable_APK_caching|APK caching]].<br />
<br />
{{Warning|As the newer version of alpine may include kernel upgrades, simply pointing the Alpine Package Manager to an Internet-based repository and running ''apk upgrade'' will not be enough, as kernel components are not upgraded when Alpine is run from memory.}}<br />
<br />
{{Upgrading_Alpine_environmentvars}}<br />
<br />
=== Upgrade Step-by-Step ===<br />
<br />
Start by checking that you have enough space on your media.<BR><br />
You need at least 400MB available space.<br />
df -h | grep "Filesystem\|$LBU_MEDIA"<br />
<br />
==== Download and verify new release ====<br />
<br />
Start downloading a new '.iso' and a '.sha1' file <br />
cd /media/$LBU_MEDIA<br />
wget -c {{Latest_1.10_alpine_iso-mirror}}{{Latest_1.10_alpine_iso-filename}}<br />
wget http://dev.alpinelinux.org/alpine/v1.10/iso/{{Latest_1.10_alpine_iso-filename}}.sha1<br />
<br />
Check integrity of the downloaded files ''(it might take some time)''<br />
sha1sum -c {{Latest_1.10_alpine_iso-filename}}.sha1<br />
''The output of the above command should say 'OK'.<BR>''<br />
''If says 'FAILED', delete the iso file and download it again.''<br />
<br />
==== Copy the new release ====<br />
<br />
Mount the ISO.<br />
<br />
mount -t iso9660 {{Latest_1.10_alpine_iso-filename}} /mnt<br />
<br />
Back up files that you have modified. For example, you might have modified ''syslinux.cfg'' to show console output on a serial port.<BR><br />
<br />
cp /media/$LBU_MEDIA/syslinux.cfg /media/$LBU_MEDIA/syslinux.cfg.my<br />
<br />
Install the '''rsync''' package if necessary, and copy the files:<br />
<br />
cd /mnt<br />
apk add rsync<br />
rsync --delete -rltv .alpine-release * /media/$LBU_MEDIA/ <br />
<br />
Restore your backed up files ''(in case you had any)''<br />
<br />
mv -f /media/$LBU_MEDIA/syslinux.cfg.my /media/$LBU_MEDIA/syslinux.cfg<br />
<br />
Make sure that all files are permanently saved in right place <br />
<br />
sync<br />
<br />
==== Clean up ====<br />
Clean up the downloaded/unpacked files<br />
cd ..<br />
umount /mnt<br />
rm /media/$LBU_MEDIA/{{Latest_1.10_alpine_iso-filename}}<br />
rm /media/$LBU_MEDIA/{{Latest_1.10_alpine_iso-filename}}.sha1<br />
<br />
=== Save changes ===<br />
Now that all upgrades are done, we should save our settings to our media (which you hopefully have backed up prior to doing this upgrade).<br />
lbu ci<br />
<br />
=== Load new kernel ===<br />
In most cases you will need to reboot Alpine (especially if there are changes in the kernel):<br />
reboot<br />
{{Note|If you know what you are doing, you might not need to reboot. But make sure that all services affected by the upgrade are restarted.}}<br />
<br />
=== Update remaining packages from Web repository ===<br />
<br />
* Check that /etc/apk/repositories reflects the current version, for example, for 1.10 it could say:<br />
http://dl-3.alpinelinux.org/alpine/v1.10/packages/main<br />
* Upgrade packages from Web.<br />
apk update<br />
apk add -u apk-tools<br />
apk upgrade -U</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Upgrading_Alpine_-_v1.9.x&diff=3729Upgrading Alpine - v1.9.x2010-05-03T14:01:27Z<p>Aalatchm: added instructions to upgrade software from http repositories</p>
<hr />
<div>This document covers upgrading from a previous version of Alpine 1.9 (or 1.10) to newer versions of 1.9 (or 1.10). Thanks to many improvements in Alpine 1.9, it is possible to easily upgrade in most scenarios.<br />
<br />
All examples/instructions/actions mentioned in this document should be executed on the box that you are planning to upgrade (unless you are instructed otherwise).<br />
<br />
== Upgrading an Alpine Linux Hard-disk installation ==<br />
<br />
When Alpine is installed to hard drive, upgrading the installation is simple.<br />
<br />
{{Using_Internet_Repositories_for_apk-tools}}<br />
<br />
Ensure you have the latest available version of the Alpine Package Manager first before upgrading anything else:<br />
apk add -u apk-tools<br />
<br />
Finally, upgrade all remaining packages, including the kernel if applicable:<br />
apk upgrade<br />
<br />
== Upgrading Separate Boot Media ==<br />
<br />
You may have an installation where the boot media being used (such as a CD, for example) is separate from the media used to store the configuration information. In this case, simply download the latest ISO, and replace the boot media contents with the contents of the latest ISO. If you are booting from a CD, this would simply mean replacing the CD with a CD made from the new image and rebooting the Alpine box. <br />
<br />
== Upgrading Alpine on CF/USB ==<br />
<br />
Your installation may consist of Alpine running on Compact Flash or USB media. In most cases, it should be sufficient to upgrade most packages using the '''Alpine Hard-disk Installation''' upgrade procedures described above. However, for new packages to survive after a reboot, you should enable [[How_to_enable_APK_caching|APK caching]].<br />
<br />
{{Warning|As the newer version of alpine may include kernel upgrades, simply pointing the Alpine Package Manager to an Internet-based repository and running ''apk upgrade'' will not be enough, as kernel components are not upgraded when Alpine is run from memory.}}<br />
<br />
{{Upgrading_Alpine_environmentvars}}<br />
<br />
=== Upgrade Step-by-Step ===<br />
<br />
Start by checking that you have enough space on your media.<BR><br />
You need at least 400MB available space.<br />
df -h | grep "Filesystem\|$LBU_MEDIA"<br />
<br />
==== Download and verify new release ====<br />
<br />
Start downloading a new '.iso' and a '.sha1' file <br />
cd /media/$LBU_MEDIA<br />
Seems files are under releases not iso anymore...<br />
http://dl-3.alpinelinux.org/alpine/v1.10/releases/alpine-1.10.1-x86.iso<br />
<br />
wget -c {{Latest_1.10_alpine_iso-mirror}}{{Latest_1.10_alpine_iso-filename}}<br />
wget http://dev.alpinelinux.org/alpine/v1.10/iso/{{Latest_1.10_alpine_iso-filename}}.sha1<br />
<br />
Check integrity of the downloaded files ''(it might take some time)''<br />
sha1sum -c {{Latest_1.10_alpine_iso-filename}}.sha1<br />
''The output of the above command should say 'OK'.<BR>''<br />
''If says 'FAILED', delete the iso file and download it again.''<br />
<br />
==== Copy the new release ====<br />
<br />
Mount the ISO.<br />
<br />
mount -t iso9660 {{Latest_1.10_alpine_iso-filename}} /mnt<br />
<br />
Back up files that you have modified. For example, you might have modified ''syslinux.cfg'' to show console output on a serial port.<BR><br />
<br />
cp /media/$LBU_MEDIA/syslinux.cfg /media/$LBU_MEDIA/syslinux.cfg.my<br />
<br />
Install the '''rsync''' package if necessary, and copy the files:<br />
<br />
cd /mnt<br />
apk add rsync<br />
rsync --delete -rltv .alpine-release * /media/$LBU_MEDIA/ <br />
<br />
Restore your backed up files ''(in case you had any)''<br />
<br />
mv -f /media/$LBU_MEDIA/syslinux.cfg.my /media/$LBU_MEDIA/syslinux.cfg<br />
<br />
Make sure that all files are permanently saved in right place <br />
<br />
sync<br />
<br />
==== Clean up ====<br />
Clean up the downloaded/unpacked files<br />
cd ..<br />
umount /mnt<br />
rm /media/$LBU_MEDIA/{{Latest_1.10_alpine_iso-filename}}<br />
rm /media/$LBU_MEDIA/{{Latest_1.10_alpine_iso-filename}}.sha1<br />
<br />
=== Save changes ===<br />
Now that all upgrades are done, we should save our settings to our media (which you hopefully have backed up prior to doing this upgrade).<br />
lbu ci<br />
<br />
=== Load new kernel ===<br />
In most cases you will need to reboot Alpine (especially if there are changes in the kernel):<br />
reboot<br />
{{Note|If you know what you are doing, you might not need to reboot. But make sure that all services affected by the upgrade are restarted.}}<br />
<br />
=== Update remaining packages from Web repository ===<br />
<br />
* Check that /etc/apk/repositories reflects the current version, for example, for 1.10 it could say:<br />
http://dl-3.alpinelinux.org/alpine/v1.10/packages/main<br />
* Upgrade packages from Web.<br />
apk update<br />
apk add -u apk-tools<br />
apk upgrade -U</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Upgrading_Alpine&diff=3516Upgrading Alpine2010-04-05T14:39:50Z<p>Aalatchm: /* What is your *present* setup */</p>
<hr />
<div>== General notes ==<br />
Alpine can be booted from various media.<BR><br />
It has also made some adjustments through time and this could also have impact on how a upgrade could be done.<BR><br />
These factors makes it hard to make a 'general' upgrade instruction that fits all scenarios.<BR><br />
The principle is still the same.<br />
<br />
To make your upgrade easy, we now present various documents that will help you in your situation.<br />
<br />
== What is your *present* setup ==<br />
You need to know... <br />
* what alpine version the box (that you are upgrading) is running at this moment.<BR>''The documents below show only how to upgrade to a newer release of the same version (e.g. 1.9.0 to 1.9.1).''<br />
* what media you are planning to upgrade (on what media is your alpine distro at this moment).<BR>''Choose '''CD''', '''USB''', '''HD/CF''' or whatever fits your setup.''<br />
<br />
<br />
Choose your current setup in the below list<br />
{|<br />
|'''alpine-1.9.x'''<br />
|[[Upgrading_Alpine_-_v1.9.x|All Installation Types]]<br />
|<br />
|<br />
|-<br />
|'''alpine-1.8.x'''<br />
|[[Upgrading_Alpine_-_CD_v1.8.x|CD]]<br />
|[[Upgrading_Alpine_-_HD_v1.8.x|HD/CF/USB]]<br />
|<br />
|-<br />
|'''alpine-1.7.x'''<br />
|<br />
|<br />
|<br />
|-<br />
|'''alpine-1.6.x'''<br />
|<br />
|<br />
|<br />
|-<br />
! &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
! &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
! &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
! &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
|}</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&diff=3484ISP Mail Server HowTo2010-03-08T21:57:27Z<p>Aalatchm: /* OpenLDAP based Address Book */</p>
<hr />
<div>== A Full Service Mail Server ==<br />
<br />
The goal of this document is to describe how to set up postfix, dovecot, clamav, dspam, roundecube, and postfixadmin for a full-featured "ISP" level mail server.<br />
<br />
The server must provide:<br />
<br />
* multiple virtual domains<br />
* admins for each domain (to add/remove virtual accounts)<br />
* Quota support per domain / account<br />
* downloading email via IMAP / IMAPS / POP3 / POP3S<br />
* relaying email for authenticated users with TLS or SSL (Submission / SMTPS protocol)<br />
* Standard filters (virus/spam/rbl/etc)<br />
* Web mail client<br />
* Value Add services<br />
<br />
== Set up Lighttpd + PHP ==<br />
<br />
PostfixAdmin needs php pgpsql and imap modules, so we do it in this step.<br />
<br />
apk add lighttpd php php-pgsql php-imap<br />
<br />
Stop and remove mini_httpd, and move ACF to lighttpd; We are setting this up to be a multi-domain virtual web server (replace host.example.com with the actual domain):<br />
<br />
mkdir -p /var/www/domains/host.example.com/www<br />
ln -s /usr/share/acf/www /var/www/domains/host.example.com/www/acf<br />
<br />
Edit /var/www/domains/host.example.com/index.html to put a simple redirection page:<br />
<br />
<pre><br />
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><br />
<html lang="en"><br />
<head><br />
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><br />
<title>host.example.com Redirector</title><br />
</head><br />
<body><br />
<ul><br />
<li><a href="/acf">ACF</a></li><br />
<li><a href="/postfixadmin">PostfixAdmin</a></li><br />
<li><a href="/roundcube">Roundcube</a></li><br />
</ul><br />
</body><br />
</pre><br />
<br />
Edit /etc/lighttpd/mod_cgi.conf to serve haserl files by adding a "" => "" cgi handler and to treat /acf/cgi-bin as a CGI directory (remove the '^')<br />
<br />
$HTTP["url"] =~ "/cgi-bin/" {<br />
# disable directory listings<br />
dir-listing.activate = "disable"<br />
# only allow cgi's in this directory<br />
cgi.assign = (<br />
".pl" => "/usr/bin/perl",<br />
".cgi" => "/usr/bin/perl",<br />
"" => ""<br />
)<br />
}<br />
<br />
Add these lines to /etc/lighttpd/lighttpd.conf to point to the new document root, and set it up to listen on port 443 (replace ''host.example.com'' with the actual domain and ''ip_address_of_server'' with the actual IP address):<br />
<br />
<pre><br />
<br />
simple-vhost.server-root = "/var/www/domains/"<br />
simple-vhost.default-host = "/host.example.com/"<br />
simple-vhost.document-root = "www/"<br />
<br />
$SERVER["socket"] == "ip_address_of_server:443" {<br />
ssl.engine = "enable"<br />
ssl.pemfile = "/etc/lighttpd/server-bundle.pem"<br />
ssl.ca-file = "/etc/lighttpd/ca-crt.pem"<br />
}<br />
</pre><br />
<br />
Ensure that the simple_vhosts module is loaded, as well as the cgi config scripts by uncommenting the following lines in /etc/lighttpd/lighttpd.conf<br />
<br />
server.modules = (<br />
# other modules may be listed<br />
"mod_simple_vhost", <br />
# other modules may be listed<br />
.<br />
.<br />
.<br />
include "mod_cgi.conf"<br />
<br />
include "mod_fastcgi.conf"<br />
<br />
<br />
Get a web certificate, and install it. If you want to use a self-signed cert, you can use [[Generating SSL certs with ACF]] or [[Generating SSL certs with ACF 1.9]]. If you create a certificate with ACF, you can create the "server-bundle.pem" and the "ca-crt.pem" file with these commands:<br />
<br />
openssl pkcs12 -nokeys -cacerts -in certificate.pfx -out /etc/lighttpd/ca-crt.pem<br />
openssl pkcs12 -nodes -in certifcate.pfx -out /etc/lighttpd/server-bundle.pem<br />
chown root:root /etc/lighttpd/server-bundle.pem<br />
chmod 400 /etc/lighttpd/server-bundle.pem<br />
<br />
<br />
'''Note:''' The server certificate ''and'' key are in the server-bundle.pem file, so it is critical that the file be read-only by user "root".<br />
<br />
Editme: We should probably only serve ACF to restricted hosts<br />
<br />
Stop and remove mini_httpd; start lighttpd, test<br />
<br />
/etc/init.d/mini_httpd stop<br />
rc-update del mini_httpd<br />
apk del mini_httpd<br />
rc-update add lighttpd<br />
/etc/init.d/lighttpd start<br />
<br />
At this point you should be able to see ACF being served with lighttpd (Note: this will work well with alpine 1.10. With earlier versions there will be problems.) https://host.example.com/acf/<br />
<br />
== Install Postgresql ==<br />
<br />
Add and configure postgresql<br />
<br />
apk add acf-postgresql postgresql-client<br />
/etc/init.d/postgresql setup<br />
/etc/init.d/postgresql start<br />
rc-update add postgresql<br />
<br />
At this point any user can connect to the sql server with "trust" mechanism. If you want to enforce password authentication (you probably do) edit /var/lib/postgresql/8.4/data/pg_hba.conf<br />
<br />
<br />
Editme: What should we recommend?<br />
<br />
<br />
Create the postfix database:<br />
<br />
psql -U postgres<br />
create user postfix with password '******';<br />
create database postfix owner postfix;<br />
\c postfix<br />
create language plpgsql;<br />
\q<br />
<br />
(Of course, use your selected password where ******* is shown above.)<br />
<br />
== Install PostfixAdmin ==<br />
<br />
We are going to install the postfix admin web front-end before we install the mail server. This just creates an interface to populate the SQL tables that postfix and dovecot will use.<br />
<br />
Download PostfixAdmin from Sourceforge. When these instructions were written, 2.3 was the current release, so (replace host.example.com with the actual domain):<br />
wget http://downloads.sourceforge.net/project/postfixadmin/postfixadmin/postfixadmin_2.3.tar.gz<br />
tar zxvf postfixadmin_2.3.tar.gz<br />
mkdir -p /var/www/domains/host.example.com/www/postfixadmin<br />
mv postfixadmin-2.3/* /var/www/domains/host.example.com/www/postfixadmin<br />
rm -rf postfixadmin*<br />
<br />
Edit /var/www/domains/host.example.com/www/postfixadmin/config.inc.php and modify at least these lines (replace host.example.com with the actual domain):<br />
<br />
$CONF['configured'] = true;<br />
$CONF['setup_password'] = ""; << Don't change this yet<br />
$CONF['database_type'] = 'pgsql';<br />
$CONF['database_host'] = 'localhost';<br />
$CONF['database_user'] = 'postfix';<br />
$CONF['database_password'] = '*****'; << The password you chose above<br />
$CONF['database_name'] = 'postfix';<br />
$CONF['database_prefix'] = "";<br />
$CONF['admin_email'] = 'you@some.email.com'; << Your email address <br />
$CONF['encrypt'] = 'md5crypt';<br />
$CONF['authlib_default_flavor'] = 'md5raw';<br />
$CONF['dovecotpw'] = "/usr/sbin/dovecotpw";<br />
$CONF['domain_path'] = 'YES';<br />
$CONF['domain_in_mailbox'] = 'NO';<br />
$CONF['aliases'] = '10'; <br />
$CONF['mailboxes'] = '10';<br />
$CONF['maxquota'] = '10';<br />
$CONF['quota'] = 'YES';<br />
$CONF['quota_multiplier'] = '1024000';<br />
$CONF['vacation'] = 'NO'; <br />
$CONF['vacation_control'] ='NO';<br />
$CONF['vacation_control_admin'] = 'NO';<br />
$CONF['alias_control'] = 'YES';<br />
$CONF['alias_control_admin'] = 'YES';<br />
$CONF['special_alias_control'] = 'YES';<br />
$CONF['fetchmail'] = 'NO';<br />
$CONF['user_footer_link'] = "http://host.example.com/postfixadmin";<br />
$CONF['footer_link'] = 'http://host.example.com/postfixadmin/main.php';<br />
$CONF['create_mailbox_subdirs_prefix']=""; <br />
$CONF['used_quotas'] = 'YES'; <br />
$CONF['new_quota_table'] = 'YES'; <br />
<br />
You should further edit /var/www/domains/host.example.com/www/postfixadmin/config.inc.php and replace all instances of "change-this-to-your.domain.tld" with your actual mail domain.<br />
<br />
Go to http://host.example.com/postfixadmin/setup.php<br />
<br />
Create the password hash, add it to the config.inc.php file<br />
<br />
Go back to http://host.example.com/postfixadmin/setup.php<br />
<br />
Create superadmin account.<br />
<br />
== Install Postfix ==<br />
<br />
Create a user for the virtual mail delivery, and get its uid/gid (you'll need the numeric uid/gid for postfix)<br />
<br />
adduser vmail -H -D -s /bin/false<br />
grep vmail /etc/passwd<br />
<br />
(In examples below, we use 1006/1006 for the uid/gid)<br />
<br />
Create the mail directory, and assign vmail as the owner<br />
mkdir -p /var/mail/domains<br />
chown -R vmail:vmail /var/mail/domains<br />
<br />
<br />
Install postfix<br />
<br />
apk add acf-postfix postfix-pgsql<br />
<br />
Edit the /etc/postfix/main.cf file. Here's an example (don't forget to replace the uid/gid):<br />
<br />
myhostname=host.example.com<br />
mydomain=example.com<br />
<br />
mydestination = localhost.$mydomain, localhost<br />
mynetworks_style = subnet<br />
mynetworks = 127.0.0.0/8<br />
<br />
virtual_mailbox_domains = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_domains_maps.cf<br />
virtual_alias_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_maps.cf,<br />
proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_maps.cf,<br />
proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_catchall_maps.cf<br />
<br />
virtual_mailbox_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_mailbox_maps.cf,<br />
proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_mailbox_maps.cf<br />
<br />
virtual_mailbox_base = /var/mail/domains/<br />
virtual_gid_maps = static:1006<br />
virtual_uid_maps = static:1006<br />
virtual_minimum_uid = 100<br />
virtual_transport = virtual<br />
<br />
<br />
# This next command means you must create a virtual<br />
# domain for the host itself - ALL mail goes through<br />
# The virtual transport<br />
<br />
mailbox_transport = virtual<br />
local_transport = virtual<br />
local_transport_maps = $virtual_mailbox_maps<br />
<br />
smtpd_helo_required = yes<br />
disable_vrfy_command = yes<br />
message_size_limit = 10240000<br />
queue_minfree = 51200000<br />
<br />
smtpd_sender_restrictions =<br />
permit_mynetworks,<br />
reject_non_fqdn_sender,<br />
reject_unknown_sender_domain<br />
<br />
smtpd_recipient_restrictions =<br />
reject_non_fqdn_recipient,<br />
reject_unknown_recipient_domain,<br />
permit_mynetworks,<br />
permit_sasl_authenticated,<br />
reject_unauth_destination,<br />
reject_rbl_client dnsbl.sorbs.net,<br />
reject_rbl_client zen.spamhaus.org,<br />
reject_rbl_client bl.spamcop.net<br />
<br />
smtpd_data_restrictions = reject_unauth_pipelining<br />
<br />
# we will use this later - This prevents cleartext authentication<br />
# for relaying<br />
smtpd_tls_auth_only = yes<br />
<br />
<br />
Now we need to create a *bunch* of files so that postfix can get the delivery information out of sql. Here's a shell script to create the scripts. Change PGPW to the password for the postfix user of the postfix SQL database.<br />
<br />
cd /etc/postfix<br />
mkdir sql<br />
PGPW="ChangeMe"<br />
<br />
cat - <<EOF >sql/pgsql_virtual_alias_domain_catchall_maps.cf<br />
user=postfix<br />
password = $PGPW<br />
hosts = localhost<br />
dbname = postfix<br />
query = Select goto From alias,alias_domain where alias_domain.alias_domain = '%d' and alias.address = '@' || alias_domain.target_domain and alias.active = true and alias_domain.active= true <br />
EOF<br />
<br />
cat - <<EOF >sql/pgsql_virtual_alias_domain_mailbox_maps.cf<br />
user=postfix<br />
password = $PGPW<br />
hosts = localhost<br />
dbname = postfix<br />
query = Select maildir from mailbox,alias_domain where alias_domain.alias_domain = '%d' and mailbox.username = '%u' || '@' || alias_domain.target_domain and mailbox.active = true and alias_domain.active<br />
EOF<br />
<br />
cat - <<EOF >sql/pgsql_virtual_alias_domain_maps.cf<br />
user=postfix<br />
password = $PGPW<br />
hosts = localhost<br />
dbname = postfix<br />
query = select goto from alias,alias_domain where alias_domain.alias_domain='%d' and alias.address = '%u' || '@' || alias_domain.target_domain and alias.active= true and alias_domain.active= true<br />
EOF<br />
<br />
cat - <<EOF >sql/pgsql_virtual_alias_maps.cf<br />
user=postfix<br />
password = $PGPW<br />
hosts = localhost<br />
dbname = postfix<br />
query = Select goto From alias Where address='%s' and active ='1'<br />
EOF<br />
<br />
cat - <<EOF >sql/pgsql_virtual_domains_maps.cf<br />
user=postfix<br />
password = $PGPW<br />
hosts = localhost<br />
dbname = postfix<br />
query = Select domain from domain where domain='%s' and active='1'<br />
EOF<br />
<br />
cat - <<EOF >sql/pgsql_virtual_mailbox_maps.cf<br />
user=postfix<br />
password = $PGPW<br />
hosts = localhost<br />
dbname = postfix<br />
query = Select maildir from mailbox where username='%s' and active=true<br />
EOF<br />
<br />
chown -R postfix:postfix sql<br />
chmod 640 sql/*<br />
<br />
<br />
At this point you should be able to start up postfix<br />
<br />
newaliases # so postfix is happy...<br />
/etc/init.d/postfix start<br />
rc-update add postfix<br />
<br />
<br />
=== Create a domain in PostfixAdmin and test ===<br />
<br />
Go to http://host.example.com/postfixadmin/<br />
<br />
Log in using the superadmin account, create a domain for the local box (e.g. example.com), and create a user mailbox (e.g. root).<br />
<br />
From the machine, send a test message:<br />
<br />
sendmail -t root@example.com<br />
subject: test<br />
.<br />
^d<br />
<br />
<br />
In /var/log/mail.log (or /var/log/messages, if you still have busybox syslogd running) you should see the message queued. The message should be in /var/mail/domains/example.com/root/new<br />
<br />
== Install Dovecot ==<br />
<br />
Dovecot is the POP3/IMAP server to retrieve mail.<br />
<br />
As before, we install dovecot: <br />
<br />
apk add acf-dovecot dovecot-pgsql<br />
<br />
edit /etc/dovecot/dovecot.conf<br />
<br />
<pre><br />
# Select only the protocols you wish to support - all are listed in the next line<br />
protocols = imap imaps pop pop3s<br />
log_path = /var/log/dovecot.log<br />
info_log_path = /var/log/dovecot-info.log<br />
disable_plaintext_auth = no<br />
<br />
# Authenticated IMAP<br />
ssl = yes<br />
ssl_cert_file = /etc/lighttpd/server-bundle.pem<br />
ssl_key_file = /etc/lighttpd/server-bundle.pem<br />
auth_verbose = yes<br />
auth_debug = no<br />
mail_location = maildir:/var/mail/domains/%d/%n<br />
auth default {<br />
mechanisms = plain<br />
passdb sql {<br />
args = /etc/dovecot/dovecot-sql.conf<br />
}<br />
userdb static {<br />
args = uid=1006 gid=1006 home=/var/mail/domains/%d/%n<br />
}<br />
}<br />
</pre><br />
<br />
Be sure to replace the uid and gid with the appropriate values for the vmail user.<br />
<br />
We need a certificate for SSL/TLS authentication, so in the example above, we use the lighttpd cert. That way when the cert is renewed/replaced, Dovecot will have access to the new cert as well. <br />
<br />
Create the /etc/dovecot/dovecot-sql.conf file:<br />
<br />
driver = pgsql<br />
connect = host=localhost dbname=postfix user=postfix password=********<br />
password_query = select username,password from mailbox where local_part = '%n' and domain = '%d'<br />
default_pass_scheme = MD5-CRYPT<br />
<br />
Again, change the password above to your postfix user password, and protect the file from prying eyes:<br />
<br />
chown root:root /etc/dovecot/dovecot-sql.conf<br />
chmod 600 /etc/dovecot/dovecot-sql.conf<br />
<br />
<br />
Start dovecot<br />
/etc/init.d/dovecot start<br />
rc-update add dovecot<br />
<br />
== Testing ==<br />
<br />
Make sure your firewall allows in ports 25(SMTP) 110 (POP3), 995 (POP3S), 143(IMAP), 993(IMAPS), or whatever subset you support. <br />
<br />
At this point, you should be able to:<br />
* Create a new domain and add users with PostfixAdmin<br />
* Send mail to those users via SMTP to port 25<br />
* Retrieve mail using the user's full email and password (e.g. username: user@example.com password: ChangeMe)<br />
<br />
== Value Add Features ==<br />
<br />
If you followed the guide above, you now have a functional mail server with many interconnected parts. The features below assume that the server is already running as described above. You should be able to add any or all of these features below to further enhance the mail service.<br />
<br />
<br />
=== Virus Scanning ===<br />
<br />
This procedure uses clamav and the postfix content_filter mechanism to scan inbound and outbound email for viruses. Infected emails are dropped. Clean emails are tagged with a "scanned by clamav" header.<br />
<br />
<br />
* Install clamav and clamsmtp:<br />
apk add acf-clamav clamsmtp<br />
* Edit the /etc/clamav/clamd.conf file if desired (not necessary in most cases)<br />
* Edit /etc/clamsmtpd.conf and verify the following lines<br />
OutAddress: 10026<br />
Listen: 127.0.0.1:10025 <br />
Header: X-Virus-Scanned: ClamAV using ClamSMTP<br />
Action: drop<br />
User: clamav <br />
* Start the daemons<br />
rc-update add clamd<br />
rc-update add freshclam<br />
rc-update add clamsmtp<br />
/etc/init.d/clamd start<br />
/etc/init.d/freshclam start<br />
/etc/init.d/clamsmtp start<br />
* Verify clamsmtp is listening on port 10025:<br />
netstat -anp | grep clamsmtp<br />
* [http://memberwebs.com/stef/software/clamsmtp/postfix.html Following the clamsmtp instructions]<br />
** edit /etc/postfix/main.cf and add:<br />
content_filter = scan:[127.0.0.1]:10025 <br />
** edit /etc/postfix/master.cf and add<br />
# AV scan filter (used by content_filter)<br />
scan unix - - n - 16 smtp<br />
-o smtp_send_xforward_command=yes<br />
-o smtp_enforce_tls=no<br />
# For injecting mail back into postfix from the filter<br />
127.0.0.1:10026 inet n - n - 16 smtpd<br />
-o content_filter=<br />
-o receive_override_options=no_unknown_recipient_checks,no_header_body_checks<br />
-o smtpd_helo_restrictions=<br />
-o smtpd_client_restrictions=<br />
-o smtpd_sender_restrictions=<br />
-o smtpd_recipient_restrictions=permit_mynetworks,reject<br />
-o mynetworks_style=host<br />
-o smtpd_authorized_xforward_hosts=127.0.0.0/8<br />
* postfix reload<br />
* Send and email into a local virtual domain - it should have the ''X-Virus-Scanned: ClamAV using ClamSMTP'' header.<br />
<br />
<br />
<br />
<br />
=== Relay for Authenticated Users ===<br />
<br />
As configured above, the mail server accepts email from the Internet, but it does not relay email. If it is a perimeter exchanger for a protected network, then you can add the protected networks to the ''mynetworks'' configuration line in /etc/postfix/main.cf<br />
<br />
This configuration change allows ''remote'' users to authenticate against the mail server and relay through it. The rules for relaying are:<br />
* Only authenticated users can relay<br />
* Authentication Credentials must be encrypted with TLS or SSL<br />
* Allow Submission and SMTPS ports for relaying (many consumer networks block port 25 - SMTP by default)<br />
The process uses the dovecot authentication mechanism (used with IMAPS) to authenticate users before they are allowed to relay through postfix.<br />
<br />
<br />
* Edit /etc/dovecot/dovecot.conf and add:<br />
# this is for postfix SASL (authenticated users can relay through us)<br />
socket listen {<br />
client {<br />
path = /var/spool/postfix/private/dovecot-auth.sock<br />
mode = 0660<br />
user = postfix<br />
group = postfix<br />
}<br />
}<br />
}<br />
* Restart dovecot<br />
/etc/init.d/dovecot restart<br />
* Edit /etc/postfix/main.cf and add:<br />
# TLS Stuff -- since we allow SASL with tls *only*, we have to set up TLS first <br />
<br />
smtpd_tls_cert_file = /etc/lighttpd/server-bundle.pem<br />
smtpd_tls_key_file = /etc/lighttpd/server-bundle.pem<br />
smtpd_tls_CAfile = /etc/lighttpd/ca-crt.pem<br />
# If tls_security_level is set to "encrypt", then SMTP rejects <br />
# unencrypted email (e.g. normal mail) which is bad.<br />
# By setting it to "may" you get TLS encrypted mail from google, slashdot, and other <br />
# interesting places. Check your logs to see who<br />
smtpd_tls_security_level = may<br />
# Log info about the negotiated encryption levels<br />
smtpd_tls_received_header = yes<br />
smtpd_tls_loglevel = 1<br />
<br />
# SASL - this allows senders to authenticiate themselves<br />
# This along with "permit_sasl_authenticated" in smtpd_recipient_restrictions allows relaying<br />
smtpd_sasl_type = dovecot<br />
smtpd_sasl_path = private/dovecot-auth.sock<br />
smtpd_sasl_auth_enable = yes<br />
smtpd_sasl_authenticated_header = yes<br />
smtpd_tls_auth_only = yes<br />
* Edit /etc/postfix/master.cf and enable the submission and smtps transports. They are probably already at the top of your master.cf file, just commented out:<br />
submission inet n - n - - smtpd<br />
-o smtpd_tls_security_level=encrypt<br />
-o smtpd_sasl_auth_enable=yes<br />
-o smtpd_client_restrictions=permit_sasl_authenticated,reject<br />
-o milter_macro_daemon_name=ORIGINATING<br />
smtps inet n - n - - smtpd<br />
-o smtpd_tls_security_level=encrypt<br />
-o smtpd_tls_wrappermode=yes<br />
-o smtpd_sasl_auth_enable=yes<br />
-o smtpd_client_restrictions=permit_sasl_authenticated,reject<br />
-o milter_macro_daemon_name=ORIGINATING<br />
*Verfiy submission and smtps are defined in /etc/services<br />
grep "submission\|ssmtp" /etc/services<br />
submission 587/tcp # mail message submission<br />
submission 587/udp<br />
smtps 465/tcp ssmtp # smtp protocol over TLS/SSL<br />
smtps 465/udp ssmtp<br />
* Restart postfix<br />
postfix reload<br />
<br />
At this point, you should be able to set up a mail client to relay through the server with TLS (port 587) or SSL (port 465) Note that "plain" authentication is used because the underlying link is encrypted. For example, in Thunderbird leave "secure authentication" unchecked, and choose STARTTLS (or TLS) for the connection security.<br />
<br />
<br />
=== Mailbox Quotas ===<br />
<br />
In the default configuration, PostfixAdmin knows about quotas, but they are not enforced. Documentation on the web mentions the [http://vda.sourceforge.net vda patch to postfix] to enforce quotas. The only bad thing... its a ''patch''. Postfix and Dovecot are both conservative systems, so if the patch isn't in the upstream source, we'll assume there's a good reason. There is a way of using quotas without patches - and it involves using dovecot's [http://wiki.dovecot.org/LDA deliver] lda for local delivery.<br />
<br />
Note: As of Jan 2010, the documention is confusing, with multiple versions of dovecot, PostfixAdmin, and Mysql referenced. These instructions apply to:<br />
* Postgresql 8.4.2 <br />
* PostfixAdmin 2.3 <br />
* Dovecot 1.2.10<br />
* Postfix 2.6.5<br />
<br />
Presumably later versions will work the same, but if not, please update the documentation and versions above.<br />
<br />
* Update /etc/dovecot.conf (old lines shown commented out):<br />
<br />
<pre><br />
# old postfix <br />
# userdb static {<br />
# args = uid=1006 gid=1006 home=/var/mail/domains/%d/%n<br />
# }<br />
<br />
# new quota support:<br />
userdb prefetch {<br />
}<br />
<br />
userdb sql {<br />
args = /etc/dovecot/dovecot-sql.conf<br />
}<br />
<br />
socket listen {<br />
client {<br />
path = /var/spool/postfix/private/dovecot-auth.sock<br />
mode = 0660<br />
user = postfix<br />
group = postfix<br />
}<br />
# These lines below are for the deliver lda<br />
master {<br />
path = /var/run/dovecot/auth-master<br />
mode = 0660<br />
user = vmail<br />
group = vmail<br />
}<br />
}<br />
}<br />
<br />
protocol imap { <br />
mail_plugins = quota imap_quota <br />
} <br />
<br />
protocol pop3 { <br />
mail_plugins = quota <br />
} <br />
<br />
dict { <br />
quotadict = pgsql:/etc/dovecot/dovecot-dict-quota.conf <br />
} <br />
<br />
plugin { <br />
quota = dict:user::proxy::quotadict <br />
} <br />
<br />
protocol lda { <br />
postmaster_address = postmaster@host.example.com<br />
mail_plugins = quota <br />
auth_socket_path = /var/run/dovecot/auth-master<br />
sendmail_path = /usr/sbin/sendmail<br />
} <br />
</pre><br />
<br />
You should already have a <tt>socket-> listen-> client</tt> section, but it is listed above to show where it goes in relationship to the <tt>socket -> listen -> master</tt> section<br />
<br />
<br />
* edit <tt>/etc/dovecot/dovecot-sql.conf</tt> and replace the user and password queries with the following (you may not have a user_query yet - add it):<br />
<br />
password_query = select username as user, password, 1006 as userdb_uid, 1006 as userdb_gid, '*:bytes=' || quota as userdb_quota_rule from mailbox where local_part = '%n' and domain = '%d'<br />
user_query = select maildir as home, 1006 as uid, 1006 as gid, '*:bytes=' || quota as quota_rule from mailbox where local_part = '%n' and domain ='%d'<br />
<br />
<br />
* create <tt>/etc/dovecot/dovecot-dict-quota.conf</tt><br />
connect = host=localhost dbname=postfix user=postfix password=********<br />
<br />
map {<br />
pattern = priv/quota/storage<br />
table = quota2<br />
username_field =username<br />
value_field = bytes<br />
}<br />
<br />
map {<br />
pattern= priv/quota/messages<br />
table = quota2<br />
username_field = username<br />
value_field = messages<br />
}<br />
<br />
Side note: [http://wiki.dovecot.org/Quota/Dict The Dovecot Quota Documentation] mentions the need for a trigger with pgsql. This was created in the PostfixAdmin install, which is why you instantiated the pgsql language when creating the database. If not, you will need to create the trigger, to reference the quota2 table, not the quota table mentioned in the dovecot docs.<br />
<br />
<br />
* create a new transport for the dovecot lda. Add the following to /etc/postfix/master.cf:<br />
# The dovecot deliver lda<br />
dovecot unix - n n - - pipe<br />
flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${user}@${nexthop}<br />
<br />
* Edit the /etc/postfix/main.cf. Replace <br />
virtual_transport = virtual <br />
with<br />
virtual_transport = dovecot<br />
dovecot_destination_recipient_limit = 1<br />
<br />
<br />
'''TODO''' This will cause over-quota emails to bounce. Which could be a source of backscatter. We need a way of checking quota limits after RBL checking but before the message is accepted in the queue.<br />
<br />
=== WebMail (RoundCube) ===<br />
<br />
[http://roundcube.net/ RoundCube] is an "ajax /Web2.0" web-mail client. These instructions are for the Alpine Linux 1.10 repository <br />
<br />
* Add the package and related php modules:<br />
apk add roundcubemail php-xml php-openssl php-mcrypt php-gd php-iconv<br />
<br />
* link the roundcube application back into the docroot<br />
ln -s /usr/share/webapps/roundcube /var/www/domains/host.example.com/www/roundcube<br />
<br />
* follow the instructions in /usr/share/webapps/roundcube/INSTALL:<br />
cd /usr/share/webapps/roundcube<br />
chown -R lighttpd:lighttpd temp logs<br />
<br />
su postgres<br />
createuser roundcube<br />
Shall the new role be a superuser? (y/n) n<br />
Shall the new role be allowed to create databases? (y/n) n<br />
Shall the new role be allowed to create more new roles? (y/n) y<br />
createdb -O roundcube -E UNICODE -T template0 roundcubemail<br />
psql roundcubemail<br />
roundcubemail=# ALTER USER roundcube WITH PASSWORD 'the_new_password';<br />
roundcubemail=# \c - roundcube<br />
roundcubemail=> \i /usr/share/webapps/roundcube/SQL/postgres.initial.sql<br />
roundcubemail=> \q<br />
exit<br />
<br />
* edit /etc/php/php.ini and set date.timezone to your local timezone, or to UTC<br />
<br />
* restart lighttpd to verify the new php libraries are used<br />
/etc/init.d/lighttpd restart<br />
<br />
* Point your browser to http://host.example.com/roundcube/installer<br />
* Start installation<br />
<br />
For the specific configuration parameters in the install step:<br />
<br />
{| class="wikitable"<br />
!Property<br />
!Setting<br />
|-<br />
| ''enable_spellcheck'' || disabled <br />
|-<br />
| ''identities_level'' || one identity with possibility to edit all params but not email address <br />
|-<br />
| ''log driver'' || syslog <br />
|-<br />
| ''sylog_id'' || roundcube <br />
|-<br />
| ''syslog_facility'' || mailsubsystem <br />
|-<br />
| ''db_dnsw'' || pgsql properties, as described above <br />
|-<br />
| ''imap_host'' || 127.0.0.1 <br />
|-<br />
| ''auto_create_user'' || enabled <br />
|-<br />
| ''smtp_server'' || 127.0.0.1<br />
|-<br />
| ''smtp_port'' || 25<br />
|-<br />
| ''smtp_user/smtp_pass'' || enable ''Use Current IMAP username and password for SMTP authentication''<br />
|-<br />
| ''smtp_log'' || enable (optional, but gives additional log record)<br />
|}<br />
<br />
The other items can be left at default settings, or adjusted if desired.<br />
<br />
* Follow the instructions in step 3 of the install to copy the files to the server<br />
* You should now be able to get to roundcube at http://host.example.com/roundcube<br />
<br />
<br />
<br />
<br />
After its working, the INSTALL file recommends removing the install directory. If you want to keep the installer around later, you can simply change the ownership and permissions. So do '''one''' of the following:<br />
cd /usr/share/webapps/roundcube<br />
rm -rf LICENSE UPGRADING INSTALL README CHANGELOG SQL installer<br />
or<br />
cd /usr/share/webapps/roundcube<br />
chown -R root:root LICENSE UPGRADING INSTALL README CHANGELOG SQL installer<br />
chmod -R 600 LICENSE UPGRADING INSTALL README CHANGELOG SQL <br />
chmod 700 SQL installer<br />
<br />
<br />
<br />
=== OpenLDAP based Address Book ===<br />
<br />
This OpenLDAP configuration uses the SQL backend, which represents information stored in PostgreSQL as an LDAP subtree for Address Book functionality for email lookups, user authentication or even <br />
replication account information between sites. This procedure uses some metainformation to translate LDAP queries to SQL queries, leaving relational schema untouched, which allows SQL and LDAP <br />
applications to inter-operate without replication, and exchange data as needed. The SQL backend uses UnixODBC to connect to PostgresSQL. <br />
<br />
* Install OpenLDAP and ODBC<br />
<br />
<pre><br />
apk add openldap libldap openldap-back-sql php-ldap unixodbc psqlodbc ca-certificates<br />
</pre><br />
<br />
'''Note''': Perhaps some packages should be installed from "edge" repository<br />
<br />
* Update "postfix" database (it will add 'id' columns to mailbox and domain tables, also will create tables and views to represent LDAP metainformation)<br />
<br />
'''Note''': These instructions are for example domain example.com. So make sure you replaced all entries of 'example' and 'com' according to your domain name parts.<br />
<br />
<pre><br />
cat - <<EOF | psql -U postgres postfix<br />
ALTER TABLE domain ADD COLUMN id SERIAL; <br />
ALTER TABLE mailbox ADD COLUMN id SERIAL; <br />
<br />
CREATE TABLE ldap_entry_objclasses (<br />
entry_id integer NOT NULL,<br />
oc_name character varying(64)<br />
);<br />
<br />
CREATE TABLE ldap_oc_mappings (<br />
id integer SERIAL,<br />
name character varying(64) NOT NULL,<br />
keytbl character varying(64) NOT NULL,<br />
keycol character varying(64) NOT NULL,<br />
create_proc character varying(255),<br />
delete_proc character varying(255),<br />
expect_return integer NOT NULL,<br />
PRIMARY KEY(id)<br />
);<br />
<br />
CREATE TABLE ldap_attr_mappings_test (<br />
id integer SERIAL,<br />
oc_map_id integer NOT NULL REFERENCES ldap_oc_mappings(id),<br />
name character varying(255) NOT NULL,<br />
sel_expr character varying(255) NOT NULL,<br />
sel_expr_u character varying(255),<br />
from_tbls character varying(255) NOT NULL,<br />
join_where character varying(255),<br />
add_proc character varying(255),<br />
delete_proc character varying(255),<br />
param_order integer NOT NULL,<br />
expect_return integer NOT NULL,<br />
PRIMARY KEY(id)<br />
);<br />
<br />
CREATE VIEW ldap_dcs AS<br />
(SELECT (domain.id + 100000) AS id, <br />
((('dc='::text || split_part((domain.domain)::text, '.'::text, 1)) || ',dc='::text) || <br />
CASE WHEN (split_part((domain.domain)::text, '.'::text, 2) = 'com'::text) THEN split_part((domain.domain)::text, '.'::text, 2) <br />
ELSE ((split_part((domain.domain)::text, '.'::text, 2) || ',dc='::text) || split_part((domain.domain)::text, '.'::text, 3)) <br />
END) AS dn, <br />
1 AS oc_map_id, <br />
100000 AS parent, <br />
0 AS keyval, <br />
domain.domain<br />
FROM domain <br />
WHERE domain.domain <> 'ALL' <br />
UNION <br />
SELECT 100000 AS id, <br />
'dc=com' AS dn, <br />
1 AS oc_map_id, <br />
0 AS parent, <br />
0 AS keyval, <br />
'com' AS domain);<br />
<br />
CREATE VIEW ldap_entries AS<br />
SELECT mailbox.id, <br />
((((('cn='::text || initcap(replace(split_part((mailbox.username)::text, '@'::text, 1), '.'::text, ' '::text))) || ',dc='::text) || <br />
split_part(split_part((mailbox.username)::text, '@'::text, 2), '.'::text, 1)) || ',dc='::text) || <br />
CASE WHEN (split_part(split_part((mailbox.username)::text, '@'::text, 2), '.'::text, 2) = 'com'::text) <br />
THEN split_part(split_part((mailbox.username)::text, '@'::text, 2), '.'::text, 2) <br />
ELSE ((split_part(split_part((mailbox.username)::text, '@'::text, 2), '.'::text, 2) || ',dc='::text) || <br />
split_part(split_part((mailbox.username)::text, '@'::text, 2), '.'::text, 3)) <br />
END) AS dn, <br />
1 AS oc_map_id, <br />
(SELECT ldap_dcs.id <br />
FROM ldap_dcs <br />
WHERE ((ldap_dcs.domain)::text = (mailbox.domain)::text)) AS parent, <br />
mailbox.id AS keyval <br />
FROM mailbox <br />
UNION <br />
SELECT ldap_dcs.id, <br />
ldap_dcs.dn, <br />
ldap_dcs.oc_map_id, <br />
ldap_dcs.parent, <br />
ldap_dcs.keyval <br />
FROM ldap_dcs;<br />
EOF<br />
</pre><br />
<br />
<br />
* Fill out LDAP tables according to following example (make sure to separate values with TABs):<br />
<br />
<pre><br />
cat - <<EOF | psql -U postgres postfix<br />
COPY ldap_attr_mappings (id, oc_map_id, name, sel_expr, sel_expr_u, from_tbls, join_where, add_proc, delete_proc, param_order, expect_return) FROM stdin;<br />
1 1 displayName mailbox.name \N mailbox \N \N \N 3 0<br />
2 1 mail mailbox.username \N mailbox \N \N \N 3 0<br />
3 1 cn mailbox.name \N mailbox \N \N \N 3 0<br />
4 1 userPassword '{CRYPT}'||mailbox.password \N mailbox \N \N \N 3 0<br />
\.<br />
<br />
COPY ldap_oc_mappings (id, name, keytbl, keycol, create_proc, delete_proc, expect_return) FROM stdin;<br />
1 exampleBox mailbox id \N \N 1<br />
\.<br />
EOF<br />
</pre><br />
<br />
* Check that "ldap_dcs" view presens something like this:<br />
<br />
<pre><br />
echo 'select * from ldap_dcs' | psql -U postgres postfix<br />
</pre><br />
<br />
<pre><br />
id | dn | oc_map_id | parent | keyval | domain <br />
--------+-----------------------------+-----------+--------+--------+--------------------<br />
100000 | dc=com | 1 | 0 | 0 | com<br />
100001 | dc=example,dc=com | 1 | 100000 | 0 | example.com<br />
</pre><br />
<br />
* Check that "ldap_entries" view presens something like this:<br />
<br />
<pre><br />
echo 'select * from ldap_entries' | psql -U postgres postfix<br />
</pre><br />
<br />
<pre><br />
id | dn | oc_map_id | parent | keyval <br />
--------+-------------------------------------------------------+-----------+--------+--------<br />
1 | cn=address1,dc=example,dc=com | 1 | 100001 | 1<br />
...<br />
123 | cn=address123,dc=example,dc=com | 1 | 100001 | 1<br />
100000 | dc=com | 1 | 0 | 0<br />
100001 | dc=example,dc=com | 1 | 100000 | 0<br />
</pre><br />
<br />
* Configure ODBC parameters<br />
<br />
Edit /etc/odbc.ini:<br />
<br />
<pre><br />
[PostgreSQL]<br />
Description = Connection to Postgres<br />
Driver = PostgreSQL<br />
Trace = Yes<br />
TraceFile = sql.log<br />
Database = postfix<br />
Servername = 127.0.0.1<br />
UserName =<br />
Password =<br />
Port = 5432<br />
Protocol = 6.4<br />
ReadOnly = No<br />
RowVersining = No<br />
ShowSystemTables = No<br />
ShowOidColumn = No<br />
FakeOidIndex = No<br />
ConnSettings =<br />
</pre><br />
<br />
Edit /etc/odbcinst.ini:<br />
<br />
<pre><br />
[PostgreSQL]<br />
Description = PostgreSQL driver for Linux<br />
Driver = /usr/lib/psqlodbcw.so<br />
Setup = /usr/lib/libodbcpsqlS.so<br />
FileUsage = 1<br />
</pre><br />
<br />
* Test ODBC connection<br />
<br />
<pre><br />
echo "select * from domain;" | isql PostgreSQL postgres<br />
</pre><br />
<br />
* Provide permission to certificate for LDAP server<br />
<br />
<pre><br />
chown ldap /etc/lighttpd/server-bundle.pem<br />
</pre><br />
<br />
* Edit LDAP schema<br />
<br />
Edit /etc/openldap/schema/example.com.schema:<br />
<br />
<pre><br />
attributetype ( 0.9.2342.19200300.100.1.3<br />
NAME ( 'mail' 'rfc822Mailbox' )<br />
DESC 'RFC1274: RFC822 Mailbox'<br />
EQUALITY caseIgnoreIA5Match<br />
SUBSTR caseIgnoreIA5SubstringsMatch<br />
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )<br />
<br />
attributetype ( 2.16.840.1.113730.3.1.241<br />
NAME 'displayName'<br />
DESC 'RFC2798: preferred name to be used when displaying entries'<br />
EQUALITY caseIgnoreMatch<br />
SUBSTR caseIgnoreSubstringsMatch<br />
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15<br />
SINGLE-VALUE )<br />
<br />
objectclass ( 2.16.840.1.113730.3.2.2<br />
NAME 'exampleBox'<br />
DESC 'example.com mailbox'<br />
MUST ( displayName $ mail $ userPassword )<br />
)<br />
<br />
# RFC 1274 + RFC 2247<br />
attributetype ( 0.9.2342.19200300.100.1.25<br />
NAME ( 'dc' 'domainComponent' )<br />
DESC 'RFC1274/2247: domain component'<br />
EQUALITY caseIgnoreIA5Match<br />
SUBSTR caseIgnoreIA5SubstringsMatch<br />
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )<br />
<br />
attributetype ( 2.5.4.46 NAME 'dnQualifier'<br />
DESC 'RFC2256: DN qualifier'<br />
EQUALITY caseIgnoreMatch<br />
ORDERING caseIgnoreOrderingMatch<br />
SUBSTR caseIgnoreSubstringsMatch<br />
SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 )<br />
</pre><br />
<br />
* Configure LDAP server<br />
<br />
Edit /etc/openldap/slapd.conf:<br />
<br />
<pre><br />
include /etc/openldap/schema/example.com.schema<br />
pidfile /var/run/openldap/slapd.pid<br />
argsfile /var/run/openldap/slapd.args<br />
<br />
TLSCipherSuite HIGH<br />
TLSCACertificateFile /etc/lighttpd/ca-crt.pem<br />
TLSCertificateFile /etc/lighttpd/server-bundle.pem<br />
TLSCertificateKeyFile /etc/lighttpd/server-bundle.pem<br />
TLSVerifyClient never <br />
<br />
# This is needed for proper representation of MD5-CRYPT format stored in database<br />
# see more details in http://strugglers.net/~andy/blog/2010/01/23/openldap-and-md5crypt/<br />
password-hash {CRYPT}<br />
password-crypt-salt-format "$1$%.8s"<br />
<br />
loglevel stats<br />
moduleload /usr/lib/openldap/back_sql.so<br />
sizelimit 3000<br />
<br />
database sql<br />
<br />
dbname PostgreSQL<br />
dbuser postfix<br />
dbpasswd *****<br />
<br />
suffix "dc=example,dc=com"<br />
rootdn "cn=admin,dc=example,dc=com"<br />
rootpw {MD5}<Hashed password for root dn><br />
<br />
upper_func "upper"<br />
strcast_func "text"<br />
concat_pattern "?||?"<br />
has_ldapinfo_dn_ru no<br />
lastmod off<br />
<br />
access to attrs=userPassword by * auth<br />
<br />
access to * by peername.ip=127.0.0.1 read<br />
### by peername.ip=<IP>%<netmask> read<br />
### by peername.ip=<IP> read<br />
by users read<br />
</pre><br />
<br />
* Set permissions for slapd.conf<br />
<br />
<pre><br />
chown ldap:ldap /etc/openldap/slapd.conf<br />
</pre><br />
<br />
* Configure startup parameters to make sure that LDAP server start AFTER PostgreSQL and listens on localhost with clear text and public IP with SSL<br />
<br />
Edit /etc/conf.d/slapd:<br />
<br />
<pre><br />
echo rc_need="postgresql" <br />
OPTS="-h 'ldaps:// ldap://127.0.0.1'"<br />
</pre><br />
<br />
* Start LDAP server<br />
<br />
<pre><br />
rc-update add slapd default<br />
/etc/init.d/slapd start<br />
</pre><br />
<br />
* Configure LDAP client utilities<br />
<br />
Edit /etc/openldap/ldap.conf<br />
<br />
<pre><br />
BASE dc=example,dc=com<br />
URI ldaps://host.example.com<br />
<br />
TLS_CACERT /etc/lighttpd/ca-crt.pem<br />
TLS_CERT /etc/lighttpd/server-bundle.pem<br />
TLS_KEY /etc/lighttpd/server-bundle.pem<br />
</pre><br />
<br />
* Test LDAP server<br />
<br />
<pre><br />
ldapsearch -z 3<br />
ldapsearch -z 3 -x -W -D cn=admin,dc=example,dc=com<br />
ldapsearch -z 3 -x -W -D cn=address1,dc=example,dc=com<br />
</pre><br />
<br />
* Configure RoundCube webmail for email lookups<br />
<br />
Edit /usr/share/webapps/roundcube/config/main.inc.php:<br />
<br />
<pre><br />
$rcmail_config['ldap_debug'] = false;<br />
...<br />
$rcmail_config['address_book_type'] = 'ldap';<br />
<br />
$rcmail_config['ldap_public']['example.com'] = array(<br />
'name' => 'example.com',<br />
'hosts' => array('127.0.0.1'),<br />
'port' => 389,<br />
'use_tls' => false,<br />
'user_specific' => false,<br />
'base_dn' => 'dc=example,dc=com',<br />
'bind_dn' => '',<br />
'bind_pass' => '',<br />
'writable' => false,<br />
'LDAP_Object_Classes' => array("top", "exampleBox"),<br />
'required_fields' => array("cn", "sn", "mail"),<br />
'LDAP_rdn' => 'mail',<br />
'ldap_version' => 3,<br />
'search_fields' => array('mail', 'cn', 'sn', 'givenName'),<br />
'name_field' => 'cn',<br />
'email_field' => 'mail',<br />
'surname_field' => 'sn',<br />
'firstname_field' => 'gn',<br />
'sort' => 'cn',<br />
'scope' => 'sub',<br />
'filter' => '(objectClass=*)', // Construct here any filter you need<br />
'fuzzy_search' => true);<br />
<br />
$rcmail_config['autocomplete_addressbooks'] = array('example.com');<br />
</pre><br />
<br />
== log rotation ==<br />
<br />
Ensure the busybox cron service is started and is configured to auto-start:<br />
<br />
/etc/init.d/cron start<br />
rc-update add cron default<br />
<br />
Add log rotate:<br />
<br />
apk add logrotate<br />
<br />
Edit ''/etc/logrotate.conf'' as desired, but the defaults should be sufficient for most people.<br />
<br />
== Configure DNS ==<br />
<br />
This server hosts three separate web applications, and these can be handled as three different virtual domains on the same web server. They will be distinguished by their DNS names, so you can choose domains for the three separate services (or at least the ones you want to publish):<br />
<br />
* ACF - Alpine Configuration Framework for managing the server<br />
* PostfixAdmin - for managing the postfix installation<br />
* RoundCube - for accessing individual mailboxes<br />
<br />
Choose three different domains (from here on known as ACF_DOMAIN, POSTFIXADMIN_DOMAIN, and ROUNDCUBE_DOMAIN) and configure DNS for all three to point to the IP address of your host. These should be DNS A records.<br />
<br />
Then, configure lighttpd to handle the three separate domains by editing /etc/lighttpd/lighttpd.conf:<br />
<br />
<pre><br />
$HTTP["host"] == "ACF_DOMAIN" {<br />
simple-vhost.server-root = "/var/www/domains/"<br />
simple-vhost.default-host = "/ACF_DOMAIN/"<br />
simple-vhost.document-root = "www/"<br />
}<br />
<br />
$HTTP["host"] == "POSTFIXADMIN_DOMAIN" {<br />
simple-vhost.server-root = "/var/www/domains/"<br />
simple-vhost.default-host = "/POSTFIXADMIN_DOMAIN/"<br />
simple-vhost.document-root = "www/"<br />
}<br />
<br />
$HTTP["host"] == "ROUNDCUBE_DOMAIN" {<br />
simple-vhost.server-root = "/var/www/domains/"<br />
simple-vhost.default-host = "/ROUNDCUBE_DOMAIN/"<br />
simple-vhost.document-root = "www/"<br />
}<br />
</pre><br />
<br />
And, then link the appropriate www directories.<br />
<pre><br />
mkdir -p /var/www/domains/ACF_DOMAIN<br />
ln -s /usr/share/acf/www /var/www/domains/ACF_DOMAIN/www<br />
<br />
mkdir -p /var/www/domains/POSTFIXADMIN_DOMAIN<br />
ln -s /var/www/domains/host.example.com/www/postfixadmin /var/www/domains/POSTFIXADMIN_DOMAIN/www<br />
<br />
mkdir -p /var/www/domains/ROUNDCUBE_DOMAIN<br />
ln -s /usr/share/webapps/roundcube /var/www/domains/ROUNDCUBE_DOMAIN/www<br />
</pre></div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Upgrading_Alpine_-_v1.9.x&diff=3308Upgrading Alpine - v1.9.x2010-01-20T20:51:32Z<p>Aalatchm: minor updates</p>
<hr />
<div>This document covers upgrading from a previous version of Alpine 1.9 to newer versions of 1.9. Thanks to many improvements in 1.9, it is possible to easily upgrade in most scenarios.<br />
<br />
All examples/instructions/actions mentioned in this document should be executed on the box that you are planning to upgrade (unless you are instructed otherwise).<br />
<br />
== Upgrading an Alpine Linux Hard-disk installation ==<br />
<br />
When Alpine is installed to hard drive, upgrading the installation is simple.<br />
<br />
{{Using_Internet_Repositories_for_apk-tools}}<br />
<br />
Ensure you have the latest available version of the Alpine Package Manager first before upgrading anything else:<br />
apk add -u apk-tools<br />
<br />
Finally, upgrade all remaining packages, including the kernel if applicable:<br />
apk upgrade<br />
<br />
== Upgrading Separate Boot Media ==<br />
<br />
You may have an installation where the boot media being used (such as a CD, for example) is separate from the media used to store the configuration information. In this case, simply download the latest ISO, and replace the boot media contents with the contents of the latest ISO. If you are booting from a CD, this would simply mean replacing the CD with a CD made from the new image and rebooting the Alpine box. <br />
<br />
== Upgrading Alpine on CF/USB ==<br />
<br />
Your installation may consist of Alpine running on Compact Flash or USB media. In most cases, it should be sufficient to upgrade most packages using the '''Alpine Hard-disk Installation''' upgrade procedures described above. However, for new packages to survive after a reboot, you should enable [[How_to_enable_APK_caching|APK caching]].<br />
<br />
'''Please note:''' As newer version of alpine may include kernel upgrades, simply pointing the Alpine Package Manager to an internet-based repository and running ''apk upgrade'' will not be enough, as kernel components are not upgraded when Alpine is run from memory.<br />
<br />
{{Upgrading_Alpine_environmentvars}}<br />
<br />
=== Upgrade Step-by-Step ===<br />
<br />
Start by checking that you have enough space on your media.<BR><br />
You need at least 400MB available space.<br />
df -h | grep "Filesystem\|$LBU_MEDIA"<br />
<br />
==== Download and verify new release ====<br />
<br />
Start downloading a new '.iso' and a '.sha1' file <br />
cd /media/$LBU_MEDIA<br />
wget -c {{Latest_1.9_alpine_iso-mirror}}{{Latest_1.9_alpine_iso-filename}}<br />
wget http://dev.alpinelinux.org/alpine/v1.9/iso/{{Latest_1.9_alpine_iso-filename}}.sha1<br />
<br />
Check integrity of the downloaded files ''(it might take some time)''<br />
sha1sum -c {{Latest_1.9_alpine_iso-filename}}.sha1<br />
''The output of the above command should say 'OK'.<BR>''<br />
''If says 'FAILED', delete the iso file and download it again.''<br />
<br />
==== Copy the new release ====<br />
<br />
Mount the ISO.<br />
<br />
mount -t iso9660 {{Latest_1.9_alpine_iso-filename}} /mnt<br />
<br />
Back up files that you have modified. For example, you might have modified ''syslinux.cfg'' to show console output on a serial port.<BR><br />
<br />
cp /media/$LBU_MEDIA/syslinux.cfg /media/$LBU_MEDIA/syslinux.cfg.my<br />
<br />
Install the '''rsync''' package if necessary, and copy the files:<br />
<br />
cd /mnt<br />
apk add rsync<br />
rsync --delete -rltv .alpine-release * /media/$LBU_MEDIA/ <br />
<br />
Restore your backed up files ''(in case you had any)''<br />
<br />
mv -f /media/$LBU_MEDIA/syslinux.cfg.my /media/$LBU_MEDIA/syslinux.cfg<br />
<br />
Make sure that all files are permanently saved in right place <br />
<br />
sync<br />
<br />
==== Clean up ====<br />
Clean up the downloaded/unpacked files<br />
cd ..<br />
umount /mnt<br />
rm /media/$LBU_MEDIA/{{Latest_1.9_alpine_iso-filename}}<br />
rm /media/$LBU_MEDIA/{{Latest_1.9_alpine_iso-filename}}.sha1<br />
<br />
=== Save changes ===<br />
Now that all upgrades are done, we should save our settings to our media (which you hopefully have backed up prior to doing this upgrade).<br />
lbu ci<br />
<br />
== Rebooting ==<br />
In most cases you will need to reboot Alpine (especially if there are changes in the kernel):<br />
reboot<br />
'''''Note:''' If you know what you are doing, you might not need to reboot. But make sure that all services affected by the upgrade are restarted.''</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Template:Upgrading_Alpine_environmentvars&diff=3297Template:Upgrading Alpine environmentvars2010-01-04T13:38:30Z<p>Aalatchm: /* Setup environment variables */ Alpine 1.9.x uses sda1 rather than hda1</p>
<hr />
<div>=== Setup environment variables ===<br />
To make the documentation a bit more 'generic' we start by setting some environment variables.<br />
vi /etc/lbu/lbu.conf<br />
Make sure that the variable 'LBU_MEDIA' is not commented (by removing the leading '#').<BR><br />
You also need to set a appropriate value for your 'LBU_MEDIA'. The media you choose will be the media where you store your settings/configuration.<BR><br />
'''''Note:''' Even if you have you alpine installed on CF, HD or USB you can still choose to save your config on some other media that suits your needs. But remember that both the media where you have your alpine AND the media where you have your config, needs to be in your box when booting it.''<br />
<br />
Example:<br />
LBU_MEDIA=sda1<br />
<br />
Now that you have your '/etc/lbu/lbu.conf' configured for your needs, we will set the environment variables (note the leading '.').<br />
. /etc/lbu/lbu.conf<br />
<br />
You can test if your environment variable was set<br />
echo $LBU_MEDIA<br />
''It should output something like 'hda1', 'usb' or whatever you just configured''<br />
<br />
=== Back up your config ===<br />
Before starting to upgrade, it's wise to save your configuration.<br />
lbu ci</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Template:Copying_Alpine_to_Flash&diff=3195Template:Copying Alpine to Flash2009-10-14T14:41:52Z<p>Aalatchm: /* Install Syslinux */ added missing commands to mount the CF card</p>
<hr />
<div>== Copy Alpine to a {{{1|Flash Medium}}} ==<br />
<br />
# Insert the removable {{{1|flash medium (CF or USB stick)}}} into the computer.<br />
# Determine the name your computer uses for your {{{1|flash medium}}}. The following step is one way to do this.<br />
#* After inserting the {{{1|flash medium}}}, run the command:<br />
#* {{Cmd|dmesg}}<br />
#* At the end of this command you should see the name of your {{{1|flash medium}}}, likely starting with "sd". (For example: "sda").<br />
#* The remainder of this document will assume that your {{{1|flash medium}}} is called /dev/sda<br />
<br />
=== Format {{{1|Flash Medium}}} ===<br />
{{Cmd|fdisk /dev/sda}}<br />
* '''p''' Print list of partitions<br />
* '''d''' Delete all partitions (this may take a few steps)<br />
* '''n''' Create a new partition<br />
* '''p''' A primary partition<br />
* '''1''' Partition number 1<br />
** Use defaults for first and last cylinder (just press [Enter] twice).<br />
* '''t''' Change partition type<br />
* '''c''' Type: Win95 FAT32 (LBA)<br />
* '''a''' Make the partition bootable (set boot flag)<br />
* '''1''' Partition number 1<br />
* '''w''' Write your changes to the device<br />
<br />
=== Install Syslinux ===<br />
# Install syslinux and dosfstools. If you have booted from an Alpine CD-ROM, use these commands:<br />
#* {{Cmd|apk add syslinux dosfstools}}<br />
#* {{Cmd|{{{|dd if=/usr/share/syslinux/mbr.bin of=/dev/sda}}}}}<br />
# Format the {{{1|flash medium}}} with a VFAT filesystem:<br />
#* {{Cmd|mkdosfs -F32 /dev/sda1}}<br />
#* {{Cmd|syslinux /dev/sda1}}<br />
#* {{Cmd|mkdir -p /media/sda1}}<br />
#* {{Cmd|mount -t vfat /dev/sda1 /media/sda1}}<br />
# Mount the Alpine Linux CD-ROM, and copy the files to the {{{1|flash medium}}}<br />
#* {{Cmd|mount /media/cdrom}}<br />
#* {{Cmd|cd /media/cdrom}}<br />
#* {{Cmd|cp -a .alpine-release * /media/sda1/ }}<br />
<br />
=== Set up a Serial Console (Optional) ===<br />
<br />
You can now edit syslinux.cfg to add a serial console to the {{{1|flash medium}}}.<br />
<br />
# Open /media/sda1/syslinux.cfg for editing.<br />
#* {{Cmd|vi /media/sda1/syslinux.cfg}}<br />
# Add the line `serial 0 9600` to the top of the file<br />
# Add the text ` console=tty=38400 console=ttyS0,9600` to the end of the "append" line.<br />
<br />
The result should look like this:<br />
serial 0 9600<br />
timeout 20<br />
prompt 1<br />
default grsec<br />
label grsec<br />
kernel /boot/grsec<br />
append initrd=/boot/grsec.gz alpine_dev=usbdisk:vfat modules=loop,cramfs,sd-mod,usb-storage console=tty1,38400 console=ttyS0,9600</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Create_a_Bootable_Compact_Flash&diff=3190Create a Bootable Compact Flash2009-10-09T15:02:57Z<p>Aalatchm: /* Requirements */ typo</p>
<hr />
<div>= Installing Alpine on Compact Flash (CF) =<br />
<br />
This document applies to Alpine Linux 1.9.0 or later.<br />
<br />
=== Requirements ===<br />
In order to follow this document, you will need:<br />
* Alpine Linux CD-ROM ([[Downloads|Download]] a .iso file containing an Alpine release.)<br />
* Computer with CF card reader<br />
* CF card<br />
** '''Note:''' Some CF card readers have problems with the faster CF cards on the market. If you experience problems booting the CF card even after checking BIOS settings, you may need to use an older card. <br />
<br />
If you already have a running Linux system (Alpine Linux 1.8.x, Debian, Gentoo, RedHat, etc.), log in as root, insert the Alpine Linux CD-ROM into the running Linux computer, and skip the next section.<br />
<br />
== Boot Alpine Linux CD-ROM ==<br />
# Insert the Alpine Linux CD into a computer.<br />
# Boot the computer from the Alpine Linux CD-ROM.<br />
#* This step may require changes to the BIOS settings to select booting from CD. <br />
# Login with the username ''root''. No password is needed.<br />
<br />
<br />
{{Copying Alpine to Flash|CF Card}}<br />
<br />
<br />
== Modify syslinux.cfg for Compact Flash Card ==<br />
<br />
Most cards are mounted as IDE drives (sda1) and not as usbdisks. Therefore, edit /media/sda1/syslinux.cfg and replace ''usbdisk'' with ''sda1''<br />
<br />
''Also, many CF card readers don't support DMA correctly, so you may need to add ''nodma'' to the ''append'' line.''<br />
<br />
<br />
<br />
{{Installing_Alpine_see_also}}</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Create_a_Bootable_Compact_Flash&diff=3189Create a Bootable Compact Flash2009-10-09T15:02:38Z<p>Aalatchm: /* Requirements */ disclaimer about fast CF cards</p>
<hr />
<div>= Installing Alpine on Compact Flash (CF) =<br />
<br />
This document applies to Alpine Linux 1.9.0 or later.<br />
<br />
=== Requirements ===<br />
In order to follow this document, you will need:<br />
* Alpine Linux CD-ROM ([[Downloads|Download]] a .iso file containing an Alpine release.)<br />
* Computer with CF card reader<br />
* CF card<br />
** '''Note:''' Some CF card readers have problems with the faster CF cards on the market. If you experience problems bootin the CF card even after checking BIOS settings, you may need to use an older card. <br />
<br />
If you already have a running Linux system (Alpine Linux 1.8.x, Debian, Gentoo, RedHat, etc.), log in as root, insert the Alpine Linux CD-ROM into the running Linux computer, and skip the next section.<br />
<br />
== Boot Alpine Linux CD-ROM ==<br />
# Insert the Alpine Linux CD into a computer.<br />
# Boot the computer from the Alpine Linux CD-ROM.<br />
#* This step may require changes to the BIOS settings to select booting from CD. <br />
# Login with the username ''root''. No password is needed.<br />
<br />
<br />
{{Copying Alpine to Flash|CF Card}}<br />
<br />
<br />
== Modify syslinux.cfg for Compact Flash Card ==<br />
<br />
Most cards are mounted as IDE drives (sda1) and not as usbdisks. Therefore, edit /media/sda1/syslinux.cfg and replace ''usbdisk'' with ''sda1''<br />
<br />
''Also, many CF card readers don't support DMA correctly, so you may need to add ''nodma'' to the ''append'' line.''<br />
<br />
<br />
<br />
{{Installing_Alpine_see_also}}</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Create_a_Bootable_Device&diff=3188Create a Bootable Device2009-10-09T14:59:14Z<p>Aalatchm: /* Alpine on USB */ updated to match CF card document using template</p>
<hr />
<div>= Installing Alpine on a USB Stick - Manual Process =<br />
<br />
This process applies to Alpine Linux 1.9.0 or later. See also: [[Installing Alpine on USB Automated]]<br />
<br />
=== Requirements ===<br />
In order to follow this document, you will need:<br />
* Alpine Linux CD-ROM ([[Downloads|Download]] a .iso file containing an Alpine release.)<br />
* Computer with CF card reader<br />
* CF card<br />
<br />
If you already have a running Linux system (Alpine Linux 1.8.x, Debian, Gentoo, RedHat, etc.), log in as root, insert the Alpine Linux CD-ROM into the running Linux computer, and skip the next section.<br />
<br />
== Boot Alpine Linux CD-ROM ==<br />
# Insert the Alpine Linux CD into a computer.<br />
# Boot the computer from the Alpine Linux CD-ROM.<br />
#* This step may require changes to the BIOS settings to select booting from CD. <br />
# Login with the username ''root''. No password is needed.<br />
<br />
{{Copying Alpine to Flash|USB stick}}<br />
<br />
{{Installing_Alpine_see_also}}</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Template:Copying_Alpine_to_Flash&diff=3186Template:Copying Alpine to Flash2009-10-09T14:53:03Z<p>Aalatchm: </p>
<hr />
<div>== Copy Alpine to a {{{1|Flash Medium}}} ==<br />
<br />
# Insert the removable {{{1|flash medium (CF or USB stick)}}} into the computer.<br />
# Determine the name your computer uses for your {{{1|flash medium}}}. The following step is one way to do this.<br />
#* After inserting the {{{1|flash medium}}}, run the command:<br />
#* {{Cmd|dmesg}}<br />
#* At the end of this command you should see the name of your {{{1|flash medium}}}, likely starting with "sd". (For example: "sda").<br />
#* The remainder of this document will assume that your {{{1|flash medium}}} is called /dev/sda<br />
<br />
=== Format {{{1|Flash Medium}}} ===<br />
{{Cmd|fdisk /dev/sda}}<br />
* '''p''' Print list of partitions<br />
* '''d''' Delete all partitions (this may take a few steps)<br />
* '''n''' Create a new partition<br />
* '''p''' A primary partition<br />
* '''1''' Partition number 1<br />
** Use defaults for first and last cylinder (just press [Enter] twice).<br />
* '''t''' Change partition type<br />
* '''c''' Type: Win95 FAT32 (LBA)<br />
* '''a''' Make the partition bootable (set boot flag)<br />
* '''1''' Partition number 1<br />
* '''w''' Write your changes to the device<br />
<br />
=== Install Syslinux ===<br />
# Install syslinux and dosfstools. If you have booted from an Alpine CD-ROM, use these commands:<br />
#* {{Cmd|apk add syslinux dosfstools}}<br />
#* {{Cmd|{{{|dd if=/usr/share/syslinux/mbr.bin of=/dev/sda}}}}}<br />
# Format the {{{1|flash medium}}} with a VFAT filesystem:<br />
#* {{Cmd|mkdosfs -F32 /dev/sda1}}<br />
#* {{Cmd|syslinux /dev/sda1}}<br />
# Mount the Alpine Linux CD-ROM, and copy the files to the {{{1|flash medium}}}<br />
#* {{Cmd|mount /media/cdrom}}<br />
#* {{Cmd|cd /media/cdrom}}<br />
#* {{Cmd|cp -a .alpine-release * /media/sda1/ }}<br />
<br />
=== Set up a Serial Console (Optional) ===<br />
<br />
You can now edit syslinux.cfg to add a serial console to the {{{1|flash medium}}}.<br />
<br />
# Open /media/sda1/syslinux.cfg for editing.<br />
#* {{Cmd|vi /media/sda1/syslinux.cfg}}<br />
# Add the line `serial 0 9600` to the top of the file<br />
# Add the text ` console=tty=38400 console=ttyS0,9600` to the end of the "append" line.<br />
<br />
The result should look like this:<br />
serial 0 9600<br />
timeout 20<br />
prompt 1<br />
default grsec<br />
label grsec<br />
kernel /boot/grsec<br />
append initrd=/boot/grsec.gz alpine_dev=usbdisk:vfat modules=loop,cramfs,sd-mod,usb-storage console=tty1,38400 console=ttyS0,9600</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Template:Copying_Alpine_to_Flash&diff=3185Template:Copying Alpine to Flash2009-10-09T14:52:34Z<p>Aalatchm: /* Copy Alpine to a {{{1|Flash Medium}}} */ added missing stuff</p>
<hr />
<div>== Copy Alpine to a {{{1|Flash Medium}}} ==<br />
<br />
# Insert the removable {{{1|flash medium (CF or USB stick)}}} into the computer.<br />
# Determine the name your computer uses for your {{{1|flash medium}}}. The following step is one way to do this.<br />
#* After inserting the {{{1|flash medium}}}, run the command:<br />
#* {{Cmd|dmesg}}<br />
#* At the end of this command you should see the name of your {{{1|flash medium}}}, likely starting with "sd". (For example: "sda").<br />
#* The remainder of this document will assume that your {{{1|flash medium}}} is called /dev/sda<br />
<br />
=== Format {{{1|Flash Medium}}} ===<br />
{{Cmd|fdisk /dev/sda}}<br />
* '''p''' Print list of partitions<br />
* '''d''' Delete all partitions (this may take a few steps)<br />
* '''n''' Create a new partition<br />
* '''p''' A primary partition<br />
* '''1''' Partition number 1<br />
** Use defaults for first and last cylinder (just press [Enter] twice).<br />
* '''t''' Change partition type<br />
* '''c''' Type: Win95 FAT32 (LBA)<br />
* '''a''' Make the partition bootable (set boot flag)<br />
* '''1''' Partition number 1<br />
* '''w''' Write your changes to the device<br />
<br />
<br />
=== Install Syslinux ===<br />
# Install syslinux and dosfstools. If you have booted from an Alpine CD-ROM, use these commands:<br />
#* {{Cmd|apk add syslinux dosfstools}}<br />
#* {{Cmd|{{{|dd if=/usr/share/syslinux/mbr.bin of=/dev/sda}}}}}<br />
# Format the {{{1|flash medium}}} with a VFAT filesystem:<br />
#* {{Cmd|mkdosfs -F32 /dev/sda1}}<br />
#* {{Cmd|syslinux /dev/sda1}}<br />
# Mount the Alpine Linux CD-ROM, and copy the files to the {{{1|flash medium}}}<br />
#* {{Cmd|mount /media/cdrom}}<br />
#* {{Cmd|cd /media/cdrom}}<br />
#* {{Cmd|cp -a .alpine-release * /media/sda1/ }}<br />
<br />
=== Set up a Serial Console (Optional) ===<br />
<br />
You can now edit syslinux.cfg to add a serial console to the {{{1|flash medium}}}.<br />
<br />
# Open /media/sda1/syslinux.cfg for editing.<br />
#* {{Cmd|vi /media/sda1/syslinux.cfg}}<br />
# Add the line `serial 0 9600` to the top of the file<br />
# Add the text ` console=tty=38400 console=ttyS0,9600` to the end of the "append" line.<br />
<br />
The result should look like this:<br />
serial 0 9600<br />
timeout 20<br />
prompt 1<br />
default grsec<br />
label grsec<br />
kernel /boot/grsec<br />
append initrd=/boot/grsec.gz alpine_dev=usbdisk:vfat modules=loop,cramfs,sd-mod,usb-storage console=tty1,38400 console=ttyS0,9600</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Create_a_Bootable_Compact_Flash&diff=3184Create a Bootable Compact Flash2009-10-09T14:38:02Z<p>Aalatchm: new updates for accuracy and clarity</p>
<hr />
<div>= Installing Alpine on Compact Flash (CF) =<br />
<br />
This document applies to Alpine Linux 1.9.0 or later.<br />
<br />
=== Requirements ===<br />
In order to follow this document, you will need:<br />
* Alpine Linux CD-ROM ([[Downloads|Download]] a .iso file containing an Alpine release.)<br />
* Computer with CF card reader<br />
* CF card<br />
<br />
If you already have a running Linux system (Alpine Linux 1.8.x, Debian, Gentoo, RedHat, etc.), log in as root, insert the Alpine Linux CD-ROM into the running Linux computer, and skip the next section.<br />
<br />
== Boot Alpine Linux CD-ROM ==<br />
# Insert the Alpine Linux CD into a computer.<br />
# Boot the computer from the Alpine Linux CD-ROM.<br />
#* This step may require changes to the BIOS settings to select booting from CD. <br />
# Login with the username ''root''. No password is needed.<br />
<br />
<br />
{{Copying Alpine to Flash|CF Card}}<br />
<br />
<br />
== Modify syslinux.cfg for Compact Flash Card ==<br />
<br />
Most cards are mounted as IDE drives (sda1) and not as usbdisks. Therefore, edit /media/sda1/syslinux.cfg and replace ''usbdisk'' with ''sda1''<br />
<br />
''Also, many CF card readers don't support DMA correctly, so you may need to add ''nodma'' to the ''append'' line.''<br />
<br />
<br />
<br />
{{Installing_Alpine_see_also}}</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Template:Copying_Alpine_to_Flash&diff=3183Template:Copying Alpine to Flash2009-10-09T14:32:52Z<p>Aalatchm: /* Copy Alpine to a {{{1|Flash Medium}}} */ formatting</p>
<hr />
<div>== Copy Alpine to a {{{1|Flash Medium}}} ==<br />
<br />
# Insert the removable {{{1|flash medium (CF or USB stick)}}} into the computer.<br />
# Determine the name your computer uses for your {{{1|flash medium}}}. The following step is one way to do this.<br />
#* After inserting the {{{1|flash medium}}}, run the command:<br />
#* {{Cmd|dmesg}}<br />
#* At the end of this command you should see the name of your {{{1|flash medium}}}, likely starting with "sd". (For example: "sda").<br />
#* The remainder of this document will assume that your {{{1|flash medium}}} is called /dev/sda<br />
# Format the {{{1|flash medium}}} with a VFAT filesystem:<br />
#* {{Cmd|mkdosfs -F32 /dev/sda1}}<br />
#* {{Cmd|syslinux /dev/sda1}}<br />
# Mount the Alpine Linux CD-ROM, and copy the files to the {{{1|flash medium}}}<br />
#* {{Cmd|mount /media/cdrom}}<br />
#* {{Cmd|cd /media/cdrom}}<br />
#* {{Cmd|cp -a .alpine-release * /media/sda1/ }}<br />
<br />
=== Set up a Serial Console (Optional) ===<br />
<br />
You can now edit syslinux.cfg to add a serial console to the {{{1|flash medium}}}.<br />
<br />
# Open /media/sda1/syslinux.cfg for editing.<br />
#* {{Cmd|vi /media/sda1/syslinux.cfg}}<br />
# Add the line `serial 0 9600` to the top of the file<br />
# Add the text ` console=tty=38400 console=ttyS0,9600` to the end of the "append" line.<br />
<br />
The result should look like this:<br />
serial 0 9600<br />
timeout 20<br />
prompt 1<br />
default grsec<br />
label grsec<br />
kernel /boot/grsec<br />
append initrd=/boot/grsec.gz alpine_dev=usbdisk:vfat modules=loop,cramfs,sd-mod,usb-storage console=tty1,38400 console=ttyS0,9600</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Template:Copying_Alpine_to_Flash&diff=3182Template:Copying Alpine to Flash2009-10-09T14:09:52Z<p>Aalatchm: </p>
<hr />
<div>== Copy Alpine to a {{{1|Flash Medium}}} ==<br />
<br />
# Insert the removable {{{1|flash medium (CF or USB stick)}}} into the computer.<br />
# Determine the name your computer uses for your {{{1|flash medium}}}. The following step is one way to do this.<br />
## After inserting the {{{1|flash medium}}}, run the command:<br />
{{Cmd|dmesg}}<br />
## At the end of this command you should see the name of your {{{1|flash medium}}}, likely starting with "sd". (For example: "sda").<br />
## The remainder of this document will assume that your {{{1|flash medium}}} is called /dev/sda<br />
# Format the {{{1|flash medium}}} with a VFAT filesystem:<br />
{{Cmd|mkdosfs -F32 /dev/sda1<br />
syslinux /dev/sda1}}<br />
# Mount the Alpine Linux CD-ROM, and copy the files to the {{{1|flash medium}}}<br />
{{Cmd|mount /media/cdrom}}<br />
{{Cmd|cd /media/cdrom}}<br />
{{Cmd|cp -a .alpine-release * /media/sda1/ }}</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Template:Copying_Alpine_to_Flash&diff=3181Template:Copying Alpine to Flash2009-10-09T14:08:52Z<p>Aalatchm: </p>
<hr />
<div># Insert the removable {{{1|flash medium (CF or USB stick)}}} into the computer.<br />
# Determine the name your computer uses for your {{{1|flash medium}}}. The following step is one way to do this.<br />
## After inserting the {{{1|flash medium}}}, run the command:<br />
{{Cmd|dmesg}}<br />
## At the end of this command you should see the name of your {{{1|flash medium}}}, likely starting with "sd". (For example: "sda").<br />
## The remainder of this document will assume that your {{{1|flash medium}}} is called /dev/sda<br />
# Format the {{{1|flash medium}}} with a VFAT filesystem:<br />
{{Cmd|mkdosfs -F32 /dev/sda1<br />
syslinux /dev/sda1}}<br />
# Mount the Alpine Linux CD-ROM, and copy the files to the {{{1|flash medium}}}<br />
{{Cmd|mount /media/cdrom}}<br />
{{Cmd|cd /media/cdrom}}<br />
{{Cmd|cp -a .alpine-release * /media/sda1/ }}</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Template:Copying_Alpine_to_Flash&diff=3180Template:Copying Alpine to Flash2009-10-09T14:07:16Z<p>Aalatchm: </p>
<hr />
<div># Insert the removable {{{1|flash medium (CF or USB stick)}}} into the computer.<br />
# Determine the name your computer uses for your {{{1|flash medium}}}. The following step is one way to do this.<br />
## After inserting the {{{1|flash medium}}}, run the command:<br />
{{Cmd|dmesg}}<br />
## At the end of this command you should see the name of your {{{1|flash medium}}}, likely starting with "sd". (For example: "sda").<br />
## The remainder of this document will assume that your {{{1|flash medium}}} is called /dev/sda<br />
# Format the {{{1|flash medium}}} with a VFAT filesystem:<br />
{{Cmd|mkdosfs -F32 /dev/sda1}}<br />
{{Cmd|syslinux /dev/sda1}}<br />
# Mount the Alpine Linux CD-ROM, and copy the files to the {{{1|flash medium}}}<br />
{{Cmd|mount /media/cdrom<br />
cd /media/cdrom<br />
cp -a .alpine-release * /media/sda1/}}</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Template:Copying_Alpine_to_Flash&diff=3179Template:Copying Alpine to Flash2009-10-09T14:06:42Z<p>Aalatchm: new template</p>
<hr />
<div># Insert the removable {{{1|flash medium (CF or USB stick)}}} into the computer.<br />
# Determine the name your computer uses for your {{{1|flash medium}}}. The following step is one way to do this.<br />
## After inserting the {{{1|flash medium}}}, run the command:<br />
{{Cmd|dmesg}}<br />
## At the end of this command you should see the name of your {{{1|flash medium}}}, likely starting with "sd". (For example: "sda").<br />
## The remainder of this document will assume that your {{{1|flash medium}}} is called /dev/sda<br />
# Format the {{{1|flash medium}}} with a VFAT filesystem:<br />
mkdosfs -F32 /dev/sda1<br />
syslinux /dev/sda1<br />
# Mount the Alpine Linux CD-ROM, and copy the files to the {{{1|flash medium}}}<br />
mount /media/cdrom<br />
cd /media/cdrom<br />
cp -a .alpine-release * /media/sda1/</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Setting_up_a_software_RAID_array&diff=3178Setting up a software RAID array2009-10-08T13:50:30Z<p>Aalatchm: /* Saving config */ add rc-update for 1.9.x</p>
<hr />
<div>This document will show how to create hard disk mirroring using cheap IDE disks.<br />
<br />
This document was written for alpine-1.3.8 or later. It is tested with alpine-1.7.7. It is tested with alpine 1.8.1.1.<br />
<br />
I will setup 1 raid device for use as physical storage for [[Setting up Logical Volumes with LVM | lvm]] .<br />
<br />
== Loading needed modules ==<br />
Start with loading the ide-disk and raid1 kernel modules. If you use SATA or SCSI disks you will not need the ide-disk module.<br />
<br />
modprobe ide-disk<br />
modprobe raid1<br />
<br />
Add them to /etc/modules so they get loaded during next reboot.<br />
<br />
echo ide-disk >> /etc/modules<br />
echo raid1 >> /etc/modules<br />
<br />
== Creating the partitions ==<br />
I will use /dev/hde and /dev/hdg in this document but you will probably use /dev/hda and /dev/hdc. Note that the disks should not be connected on the same IDE bus (sharing the same IDE cable). To find what disks you have available, look in /proc/partitions or look at the /dev/disk* links that the mdev system has created.<br />
ls -l /dev/disk*<br />
lrwxrwxrwx 1 root root 3 Oct 17 13:23 /dev/disk -> hda<br />
lrwxrwxrwx 1 root root 3 Oct 17 13:23 /dev/disk0 -> hda<br />
lrwxrwxrwx 1 root root 3 Oct 17 13:23 /dev/disk1 -> hdc<br />
<br />
Create the partitions using fdisk.<br />
<br />
fdisk /dev/hda<br />
<br />
I will create one single partition of type Linux raid autodetect. Use '''n''' in fdisk to create the partition and '''t''' to set type. Logical volumes will be created later. My partition table looks like this ('p' to print partition table):<br />
<br />
Device Boot Start End Blocks Id System<br />
/dev/hda1 1 17753 8388261 fd Linux raid autodetect<br />
<br />
Use '''w''' to '''w'''rite and quit.<br />
Do the same with your second disk.<br />
<br />
fdisk /dev/hdc<br />
<br />
Mine looks like this:<br />
Device Boot Start End Blocks Id System<br />
/dev/hdc1 1 17753 8388261 fd Linux raid autodetect<br />
<br />
== Setting up the raid array ==<br />
Install mdadm to set up the arrays.<br />
<br />
apk_add mdadm<br />
<br />
If you use an alpine version earlier than 1.7.3 you need to make the /dev nodes before creating the arrays.<br />
<br />
mknod /dev/md0 b 9 0<br />
<br />
In alpine 1.8.1.1 you have to run "mdev -s" to update your /dev entries.<br />
<br />
Create the array.<br />
mdadm --create --level=1 --raid-devices=2 /dev/md0 /dev/hda1 /dev/hdc1<br />
<br />
== Monitoring sync status ==<br />
You should now be able to see the array syncronize by looking at the contents of /proc/mdstat.<br />
<br />
~ # cat /proc/mdstat <br />
Personalities : [raid1] <br />
md0 : active raid1 hdc1[1] hda1[0]<br />
8388160 blocks [2/2] [UU]<br />
[=========>...........] resync = 45.3% (3800064/8388160) finish=0.3min speed=200003K/sec<br />
<br />
unused devices: <none><br />
<br />
You don't need to wait til it is fully syncronized to continue.<br />
<br />
== Saving config ==<br />
Create the /etc/mdadm.conf file so mdadm knows how your raid setup is:<br />
mdadm --detail --scan > /etc/mdadm.conf<br />
<br />
To make sure the raid devices start during the next reboot run:<br />
rc-update add mdadm-raid<br />
Or, on Alpine 1.8 or earlier:<br />
rc_add -s 10 -k mdadm-raid<br />
<br />
The ''-s 10'' option is to make sure that the raid arrays are started early, before things like lvm and localmount.<br />
<br />
Use ''lbu commit'' as usual to save configs to usb or floppy.<br />
<br />
The raid device /dev/md0 is now ready to be used with [[Setting up Logical Volumes with LVM|lvm]] or mkfs.</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Setting_up_Logical_Volumes_with_LVM&diff=3010Setting up Logical Volumes with LVM2009-09-02T17:35:52Z<p>Aalatchm: corrected for 1.9: start localmount before swap; added rc-update commands</p>
<hr />
<div>This document how to create logical volumes in Alpine using lvm2.<br />
<br />
LVM is collection of programs that allow larger physical disks to be reassembled into "logical" disks that can be shrunk or expanded as data needs change.<br />
<br />
In this document we will use a [[Setting up a software raid1 array | software raid1 device]] as physical storage for our logical volumes. We will set up a swap partition and a data partition for [[ Setting up a basic vserver | vservers ]]<br />
=== Installing LVM software ===<br />
First we need to load the kernel driver, ''dm-mod''<br />
<br />
modprobe dm-mod<br />
<br />
We also want it to be loaded during next reboot.<br />
<br />
echo dm-mod >> /etc/modules<br />
<br />
We also need the userspace programs.<br />
apk_add lvm2<br />
<br />
=== Preparing the physical volumes ===<br />
First we need to tell LVM that de partition is available as a physical volume and can be added to a volume group. In this example we use a software raid array as physical volume.<br />
pvcreate /dev/md0<br />
<br />
=== Preparing the Volume Group ===<br />
We can then create a volume group and add the physical volume ''/dev/md0''<br />
vgcreate vg0 /dev/md0<br />
<br />
If we later need more space we can add additional physcal volumes with ''vgextend''. All physcal disks/partitions added need to be prepared with ''pvcreate''.<br />
<br />
=== Creating Logical volumes ===<br />
In the volume group we can create logical volumes. To create a 1GB volume called ''swap'' and a 6GB volume called 'vservers'' on the volume group ''vg0'' we run<br />
lvcreate -n swap -L 1G vg0<br />
lvcreate -n vservers -L 6G vg0<br />
<br />
=== Display Logical Volumes ===<br />
You can now se the logical volumes with the lvdisplay utility.<br />
<br />
lvdisplay<br />
--- Logical volume ---<br />
LV Name /dev/vg0/swap<br />
VG Name vg0<br />
LV UUID a4NYOi-FQP6-Lj5Q-0TYk-Jjtk-Qxjt-nxeBPn<br />
LV Write Access read/write<br />
LV Status available<br />
# open 0<br />
LV Size 1.00 GB<br />
Current LE 256<br />
Segments 1<br />
Allocation inherit<br />
Read ahead sectors 0<br />
Block device 253:0<br />
<br />
--- Logical volume ---<br />
LV Name /dev/vg0/vservers<br />
VG Name vg0<br />
LV UUID 16VMmy-7I0s-eeoW-tL2V-JrlN-jM6C-d0wEg0<br />
LV Write Access read/write<br />
LV Status available<br />
# open 0<br />
LV Size 6.00 GB<br />
Current LE 1536<br />
Segments 1<br />
Allocation inherit<br />
Read ahead sectors 0<br />
Block device 253:1<br />
<br />
=== Rename Logical Volumes ===<br />
<br />
lvrename /dev/vg0/vservers /dev/vg0/database<br />
<br />
=== Extend Logical Volumes ===<br />
If you want to add space and the volume has the room for it...<br />
<br />
lvextend -L +50G /dev/vg0/vservers<br />
<br />
If you want to set the space to a new larger size...<br />
<br />
lvextend -L 10G /dev/vg0/vservers<br />
<br />
=== Start LVM during Boot ===<br />
We want lvm to init the logical volumes during boot. There is a boot service named ''lvm'' to do this. If your volumes are on raid, make sure that ''/etc/init.d/lvm'' is started after mdadm-raid.<br />
rc-update add lvm<br />
<br />
Or, on Alpine Linux 1.8 or earlier:<br />
rc_add -s 12 -k lvm<br />
<br />
=== Setting up swap ===<br />
Now we have our devices in /dev/vg0 and can use them as normal disk paritions. To set up swap:<br />
<br />
mkswap /dev/vg0/swap<br />
<br />
Add the following line to your ''/etc/fstab'':<br />
/dev/vg0/swap none swap sw 0 0<br />
<br />
<br />
=== Setting up /vservers partition ===<br />
Finally we want to set up an XFS partition for /vservers.<br />
<br />
Install xfsprogs.<br />
<br />
apk_add xfsprogs<br />
<br />
Create filesystem on /dev/vg0/vservers.<br />
mkfs.xfs /dev/vg0/vservers<br />
<br />
Add the mount information to your /etc/fstab: NOTE:tagxid may cause this not to mount. Try this by hand and check dmesg to see if there are any errors<br />
/dev/vg0/vservers /vservers xfs noatime,tagxid 0 0<br />
<br />
Note that the ''tagxid'' option is specific for setting up vserver [http://oldwiki.linux-vserver.org/Disk+Limits disk limits] so it might be you don't want it. The ''noatime'' option is to increase performance but you will no longer know when files were accessed last time.<br />
<br />
=== Starting localmount and swap ===<br />
<br />
Now we can start the ''localmount'' boot service to mount our partition.<br />
/etc/init.d/localmount start<br />
<br />
Make sure we run ''localmount'' during boot too, and that it is done after lvm.<br />
rc-update add localmount<br />
<br />
Or, on Alpine Linux 1.8 or earlier:<br />
rc_add -s 14 -k localmount<br />
<br />
<br />
Start the swap service and make sure it starts during next reboot and that it starts '''after''' lvm.<br />
<br />
/etc/init.d/swap start<br />
rc-update add swap<br />
<br />
Or, on Alpine Linux 1.8 or earlier:<br />
/etc/init.d/swap start<br />
rc_add -s 14 -k swap<br />
<br />
<br />
=== More Info on LVM ===<br />
For more information, have a look at the [http://tldp.org/HOWTO/LVM-HOWTO/commontask.html common tasks] section in the [http://tldp.org/HOWTO/LVM-HOWTO/index.html LVM Howto].</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Alpine_Linux:Documentation&diff=2962Alpine Linux:Documentation2009-08-06T15:44:50Z<p>Aalatchm: add link to Writing User Documentation for ACF</p>
<hr />
<div>== User Documentation ==<br />
Documentation how to install and use the Alpine distro.<br />
<br />
* [[Installing Alpine on CD]]<br />
* [[Installing Alpine on USB]]<br />
* [[Installing Alpine on Compact Flash]]<br />
* [[Upgrading Alpine]]<br />
* [[Alpine package management]] ''(How to add/remove packages on your Alpine)''<br />
* [[Alpine boot services]] ''(Configure a service to automatically boot at next reboot)''<br />
* [[Alpine local backup]] ''(Permanently store your modifications in case your box needs reboot)''<br />
* [[Comparison with Gentoo and Debian]]<br />
* Submitting [http://bugs.alpinelinux.org Problem Reports]<br />
<br />
=== HOWTOS ===<br />
<br />
==== Installation ====<br />
* [[Bootstrapping Alpine on Soekris net4xxx]]<br />
* [[Bootstrapping Alpine on PC Engines ALIX.3]]<br />
* [[Setting up a software raid1 array]]<br />
* [[Setting up Logical Volumes with LVM]]<br />
* [[Setting up a /var partition on software IDE raid1]]<br />
* [[Native Harddisk Install]]<br />
* [[Installing XUbuntu using Alpine boot floppy]]<br />
<br />
==== Networking ====<br />
* [[Setting up a OpenVPN-server with Alpine]]<br />
* [[Setting up traffic monitoring using rrdtool (and snmp)]]<br />
* [[Setting up Zaptel/Asterisk on Alpine]]<br />
* [[Using HSDPA modem]]<br />
* [[Using Alpine on Windows domain with IPSEC isolation]]<br />
* [[Using Racoon for Remote Sites]]<br />
<br />
==== Misc ====<br />
* [[Setting up lm_sensors]]<br />
* [[Setting up Satellite Internet Connection]]<br />
* [[Setting up Streaming an Asterisk Channel]]<br />
* [[Formatting HD/Floppy/Other]]<br />
* [[Setting up Transmission (bittorrent) with Clutch WebUI]]<br />
* [[Hosting_services_on_Alpine]] ''(This applies to hosting mail, webservices and other services)''<br />
** [[Setting_up_postfix_with_virtual_domains]]<br />
** [[Protecting your email server with Alpine]]<br />
** [[Hosting Web/Email services on Alpine]]<br />
** [[Setting_up_trac_wiki]]<br />
* [[Running Alpinelinux As a QEMU networked Guest ]]<br />
* [[Screen on console]]<br />
* [[Using espeak on AlpineLinux]]<br />
* [[Generating SSL certs with ACF]]<br />
* [[Setting up a ssh-server]]<br />
* [[Changing passwords]]<br />
<br />
==== iSCSI ====<br />
* [[iSCSI Target and Initiator Configuration]]<br />
* [[iSCSI Raid and Clustered File Systems]]<br />
<br />
=== Vserver ===<br />
* [[Setting up a basic vserver]]<br />
<br />
== Developer Documentation ==<br />
Documentation how to build and modify the Alpine distro.<br />
<br />
* [[Alpine Package Testing Suite]]<br />
* [[Alpine Configuration Framework Design]] (Why ACF is the way it is)<br />
* [[Development using git]]<br />
* [[Installing Alpine on a virtual machine]]<br />
* [[Writing User Documentation for ACF]]<br />
<br />
=== Alpine 1.9.x build system ===<br />
After Alpine 1.8 is released we will switch to a new build system. Those docs here below is for bulding packages in Alpine 1.9 and later.<br />
<br />
* [[Setting up the build environment]]<br />
* [[Creating an Alpine package]]<br />
* [[Creating_an_Alpine_1.9_iso]] (This page is experimental and might go away or move in the future)<br />
<br />
=== Obsolete docs ===<br />
* [[Setting up the build environment 1.7]]<br />
* [[Newbie Guide to Building an apk]]<br />
* [[Creating patches]]<br />
<br />
== Misc. References ==<br />
Other useful references.<br />
<br />
* http://www.metoffice.gov.uk/research/nwp/external/fcm/doc/user_guide/working_practices.html - Some guidelines on use of Trac and SVN</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Upgrading_Alpine_-_v1.9.x&diff=2886Upgrading Alpine - v1.9.x2009-07-14T13:25:18Z<p>Aalatchm: /* Download a new Alpine Linux release */</p>
<hr />
<div>== Upgrading Alpine 1.9.x that runs on HD/CF/USB ==<br />
This document applies to alpine which is installed on HardDisk(HD), CompactFlash(CF) or USB.<BR><br />
<br />
All examples/instructions/actions mentioned in this document should be executed on the box that you are planning to upgrade (unless you are instructed otherwise).<br />
<br />
{{Upgrading_Alpine_environmentvars}}<br />
<br />
== Download a new Alpine Linux release ==<br />
Start by checking that you have enough space on your media.<BR><br />
You need at least 400MB available space.<br />
df -h | grep "Filesystem\|$LBU_MEDIA"<br />
<br />
Start downloading a new '.iso' and a '.sha1' file <br />
cd /media/$LBU_MEDIA<br />
wget -c {{Latest_1.9_alpine_iso-mirror}}{{Latest_1.9_alpine_iso-filename}}<br />
wget http://dev.alpinelinux.org/alpine/v1.9/iso/{{Latest_1.9_alpine_iso-filename}}.sha1<br />
<br />
Check integrity of the downloaded files ''(it might take some time)''<br />
sha1sum -c {{Latest_1.9_alpine_iso-filename}}.sha1<br />
''The output of the above command should say 'OK'.<BR>''<br />
''If says 'FAILED', delete the iso file and download it again.''<br />
<br />
== Copy the new release ==<br />
<br />
Mount the ISO.<br />
<br />
mkdir /tmp/alpine-new<br />
mount -t iso9660 {{Latest_1.9_alpine_iso-filename}} /tmp/alpine-new<br />
<br />
<br />
Back up file that you have modified ''(below is a list of files that might need backing up)''<BR><br />
'''''syslinux.cfg:''' You might have modified it to show console on a serial port''<br />
<br />
cp /media/$LBU_MEDIA/syslinux.cfg /media/$LBU_MEDIA/syslinux.cfg.my<br />
<br />
Copy the files:<br />
<br />
cd /tmp/alpine-new<br />
rsync --delete -rltv .alpine-release * /media/$LBU_MEDIA/ <br />
<br />
Restore your backed up files ''(in case you had any)''<br />
<br />
mv -f /media/$LBU_MEDIA/syslinux.cfg.my /media/$LBU_MEDIA/syslinux.cfg<br />
<br />
Make sure that all files are permanently saved in right place <br />
<br />
sync<br />
<br />
{{Upgrading_Alpine_executeupgradescript}}<br />
<br />
== Clean up ==<br />
Clean up the downloaded/unpacked files<br />
umount /tmp/alpine-new<br />
rmdir /tmp/alpine-new<br />
rm /media/$LBU_MEDIA/{{Latest_1.9_alpine_iso-filename}}<br />
rm /media/$LBU_MEDIA/{{Latest_1.9_alpine_iso-filename}}.sha1<br />
<br />
== Save changes ==<br />
Now that all upgrades are done, we should save our settings to our media (which you hopefully have backed up).<br />
lbu ci<br />
<br />
== Rebooting ==<br />
In most cases you will need to reboot Alpine (especially if there are changes in the kernel):<br />
reboot<br />
'''''Note:''' If you know what you are doing, you might not need to reboot.<BR>But make sure that all services affected by the upgrade are restarted.''</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Upgrading_Alpine_-_v1.9.x&diff=2885Upgrading Alpine - v1.9.x2009-07-14T13:24:19Z<p>Aalatchm: Created new page using rsync, for 1.9.x</p>
<hr />
<div>== Upgrading Alpine 1.9.x that runs on HD/CF/USB ==<br />
This document applies to alpine which is installed on HardDisk(HD), CompactFlash(CF) or USB.<BR><br />
<br />
All examples/instructions/actions mentioned in this document should be executed on the box that you are planning to upgrade (unless you are instructed otherwise).<br />
<br />
{{Upgrading_Alpine_environmentvars}}<br />
<br />
== Download a new Alpine Linux release ==<br />
Start by checking that you have enough space on your media.<BR><br />
You need at least 400MB available space.<br />
df -h | grep "Filesystem\|$LBU_MEDIA"<br />
<br />
Start downloading a new '.iso' and a '.sha1' file <br />
cd /media/$LBU_MEDIA<br />
wget -c {{Latest_1.9_alpine_iso-mirror}}{{Latest_1.9_alpine_iso-filename}}<br />
wget http://dev.alpinelinux.org/alpine/v1.9/iso/{{Latest_1.9_alpine_iso-filename}}.sha1<br />
<br />
Check integrity of the downloaded files ''(it might take some time)''<br />
sha1sum -c {{Latest_1.8_alpine_gz-filename}}.sha1<br />
''The output of the above command should say 'OK'.<BR>''<br />
''If says 'FAILED', delete the iso file and download it again.''<br />
<br />
== Copy the new release ==<br />
<br />
Mount the ISO.<br />
<br />
mkdir /tmp/alpine-new<br />
mount -t iso9660 {{Latest_1.9_alpine_iso-filename}} /tmp/alpine-new<br />
<br />
<br />
Back up file that you have modified ''(below is a list of files that might need backing up)''<BR><br />
'''''syslinux.cfg:''' You might have modified it to show console on a serial port''<br />
<br />
cp /media/$LBU_MEDIA/syslinux.cfg /media/$LBU_MEDIA/syslinux.cfg.my<br />
<br />
Copy the files:<br />
<br />
cd /tmp/alpine-new<br />
rsync --delete -rltv .alpine-release * /media/$LBU_MEDIA/ <br />
<br />
Restore your backed up files ''(in case you had any)''<br />
<br />
mv -f /media/$LBU_MEDIA/syslinux.cfg.my /media/$LBU_MEDIA/syslinux.cfg<br />
<br />
Make sure that all files are permanently saved in right place <br />
<br />
sync<br />
<br />
{{Upgrading_Alpine_executeupgradescript}}<br />
<br />
== Clean up ==<br />
Clean up the downloaded/unpacked files<br />
umount /tmp/alpine-new<br />
rmdir /tmp/alpine-new<br />
rm /media/$LBU_MEDIA/{{Latest_1.9_alpine_iso-filename}}<br />
rm /media/$LBU_MEDIA/{{Latest_1.9_alpine_iso-filename}}.sha1<br />
<br />
== Save changes ==<br />
Now that all upgrades are done, we should save our settings to our media (which you hopefully have backed up).<br />
lbu ci<br />
<br />
== Rebooting ==<br />
In most cases you will need to reboot Alpine (especially if there are changes in the kernel):<br />
reboot<br />
'''''Note:''' If you know what you are doing, you might not need to reboot.<BR>But make sure that all services affected by the upgrade are restarted.''</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Template:Latest_1.9_alpine_iso-filename&diff=2884Template:Latest 1.9 alpine iso-filename2009-07-14T13:08:00Z<p>Aalatchm: Created page with 'alpine-1.9.0_alpha16-i386.iso'</p>
<hr />
<div>alpine-1.9.0_alpha16-i386.iso</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Changing_passwords_for_ACF&diff=2856Changing passwords for ACF2009-06-12T14:50:18Z<p>Aalatchm: corrected the echo command with the `-n` flag</p>
<hr />
<div>== Changing passwords in Alpine Linux ==<br />
<br />
''Note: this document covers version 1.8 and under. In future versions, the hope is to store the ACF user details in a database to make it more secure.''<br />
<br />
This provides documentation for beginner Alpine Linux users on how to change passwords for the console login as well as the ACF. It is pretty simple.<br />
<br />
=== Change the password from the command line ===<br />
<br />
To change a system user's password on the command line, do the following, where 'username' could be a system user, such as '''root''':<br />
<br />
''passwd username''<br />
<br />
The logins and passwords for the ACF users are stored in a separate location: ''/etc/acf/passwd''. Although of course you should change the ACF (web interface) user passwords via the ''System >> User Management'' page, there may be times when you cannot remember the login password for the ACF user, and have to change it from the command line:<br />
<br />
The syntax for the '''/etc/acf/passwd''' file is as follows:<br />
<br />
username:md5sumpassword::ROLE<br />
<br />
For example, change the default ACF user ''Alpine'' as follows:<br />
<br />
Generate a md5sum hash of the password '''testing123''', and send it to the passwd file:<br />
''echo -n "testing123" | md5sum >> /etc/acf/passwd''<br />
<br />
Edit the passwd file to put the hash in the correct place as shown below, deleting the existing hash:<br />
Alpine:92707c3c2766ce04133e0f85681add8b::ADMIN<br />
<br />
=== To change passwords from the ACF Interface ===<br />
<br />
Log on as a user with the Admin role, which has rights to change user passwords other than it's own.<br />
<br />
Browse to ''System >> User Management''<br />
<br />
Under the Existing Account section, click '''Edit this account''' under the user whose password you want to change.<br />
<br />
Enter the new password in the '''Password''' and '''Password (Confirm)''' fields.<br />
<br />
Click '''Save''' to save the changes.<br />
<br />
Finally, remember to commit all changes: ''lbu ci''</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Writing_User_Documentation_for_ACF&diff=2823Writing User Documentation for ACF2009-06-01T13:16:57Z<p>Aalatchm: better introduction</p>
<hr />
<div>= Guidelines on User Documentation for ACF =<br />
<br />
Many users of Alpine Linux devices may use only the ACF Web interface. Therefore, it is beneficial to have a clear, consistent way of documenting procedures with ACF. These guidelines can be used to write concise documents that use ACF instead of the command line.<br />
<br />
== Basic suggestions ==<br />
*Write names and labels ''as they appear in ACF'', such as "DNScache" instead of dnscache.<br />
*Avoid using extra nouns such as "menu option," "tab," "section," etc. for simplicity. The formatting below should be sufficient.<br />
* Specify the entire navigation, so that the user can follow the instructions no matter where he starts.<br />
<br />
== Formatting ==<br />
<br />
Here is an example of the suggested formatting:<br />
<br />
''System: '''Local Backups''' > '''Status''' > Commit Changes: '''Commit'''<br />
<br />
Below is the formatting for common items in user documentation. All navigation strings should be in ''italics'' (or in plaintext, use forward slashes <code>/NAVIGATION > EXAMPLE/</code>).<br />
<br />
*Menu Choices, Tabs, Buttons, Links<br />
**Any text the user needs to click on should be in '''''bold (italic) typeface''''' (or in plaintext, use asterisks <code>*BUTTONNAME*</code>). The text should then be followed by a greater-than symbol ">".<br />
**Links may be preceded by a label and a colon ":".<br />
*Section Headings<br />
**Headings should be followed by a colon ":".<br />
*Check Boxes<br />
**Check boxes should be followed by ''[X]'' for selected, and ''[_]'' for unselected.<br />
*Fields<br />
**Field names have no special formatting.<br />
*Drop-down Boxes<br />
**Use a greater-than symbol ">" between the label of the box and the option to choose.<br />
<br />
=== Examples ===<br />
''System: '''Local Backups'''<br />
''System: '''Local Backups''' > '''Status''' > Commit Changes: Simulate a commit [X]<br />
''System: '''Local Backups''' > '''Status''' > Commit Changes: Simulate a commit [_]<br />
''System: '''Local Backups''' > '''Config''' > System Info: Media for Commit > usb''<br />
''System: '''Local Backups''' > '''Config''' > Edit Included Files: Included item(s)<br />
''System: '''Logfiles''' > '''Status''' > /var/log/messages: '''Tail'''</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Writing_User_Documentation_for_ACF&diff=2822Writing User Documentation for ACF2009-05-29T20:54:00Z<p>Aalatchm: </p>
<hr />
<div>= Guidelines on User Documentation for ACF =<br />
<br />
Many users of Alpine Linux devices may use only the ACF Web interface.<br />
<br />
== Basic suggestions ==<br />
*Write names and labels ''as they appear in ACF'', such as "DNScache" instead of dnscache.<br />
*Avoid using extra nouns such as "menu option," "tab," "section," etc. for simplicity. The formatting below should be sufficient.<br />
* Specify the entire navigation, so that the user can follow the instructions no matter where he starts.<br />
<br />
== Formatting ==<br />
<br />
Here is an example of the suggested formatting:<br />
<br />
''System: '''Local Backups''' > '''Status''' > Commit Changes: '''Commit'''<br />
<br />
Below is the formatting for common items in user documentation. All navigation strings should be in ''italics'' (or in plaintext, use forward slashes <code>/NAVIGATION > EXAMPLE/</code>).<br />
<br />
*Menu Choices, Tabs, Buttons, Links<br />
**Any text the user needs to click on should be in '''''bold (italic) typeface''''' (or in plaintext, use asterisks <code>*BUTTONNAME*</code>). The text should then be followed by a greater-than symbol ">".<br />
**Links may be preceded by a label and a colon ":".<br />
*Section Headings<br />
**Headings should be followed by a colon ":".<br />
*Check Boxes<br />
**Check boxes should be followed by ''[X]'' for selected, and ''[_]'' for unselected.<br />
*Fields<br />
**Field names have no special formatting.<br />
*Drop-down Boxes<br />
**Use a greater-than symbol ">" between the label of the box and the option to choose.<br />
<br />
=== Examples ===<br />
''System: '''Local Backups'''<br />
''System: '''Local Backups''' > '''Status''' > Commit Changes: Simulate a commit [X]<br />
''System: '''Local Backups''' > '''Status''' > Commit Changes: Simulate a commit [_]<br />
''System: '''Local Backups''' > '''Config''' > System Info: Media for Commit > usb''<br />
''System: '''Local Backups''' > '''Config''' > Edit Included Files: Included item(s)<br />
''System: '''Logfiles''' > '''Status''' > /var/log/messages: '''Tail'''</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Writing_User_Documentation_for_ACF&diff=2821Writing User Documentation for ACF2009-05-29T20:53:36Z<p>Aalatchm: added details</p>
<hr />
<div>= Guidelines on Writing User Documentation for ACF =<br />
<br />
Many users of Alpine Linux devices may use only the ACF Web interface.<br />
<br />
== Basic suggestions ==<br />
*Write names and labels ''as they appear in ACF'', such as "DNScache" instead of dnscache.<br />
*Avoid using extra nouns such as "menu option," "tab," "section," etc. for simplicity. The formatting below should be sufficient.<br />
* Specify the entire navigation, so that the user can follow the instructions no matter where he starts.<br />
<br />
== Formatting ==<br />
<br />
Here is an example of the suggested formatting:<br />
<br />
''System: '''Local Backups''' > '''Status''' > Commit Changes: '''Commit'''<br />
<br />
Below is the formatting for common items in user documentation. All navigation strings should be in ''italics'' (or in plaintext, use forward slashes <code>/NAVIGATION > EXAMPLE/</code>).<br />
<br />
*Menu Choices, Tabs, Buttons, Links<br />
**Any text the user needs to click on should be in '''''bold (italic) typeface''''' (or in plaintext, use asterisks <code>*BUTTONNAME*</code>). The text should then be followed by a greater-than symbol ">".<br />
**Links may be preceded by a label and a colon ":".<br />
*Section Headings<br />
**Headings should be followed by a colon ":".<br />
*Check Boxes<br />
**Check boxes should be followed by ''[X]'' for selected, and ''[_]'' for unselected.<br />
*Fields<br />
**Field names have no special formatting.<br />
*Drop-down Boxes<br />
**Use a greater-than symbol ">" between the label of the box and the option to choose.<br />
<br />
=== Examples ===<br />
''System: '''Local Backups'''<br />
''System: '''Local Backups''' > '''Status''' > Commit Changes: Simulate a commit [X]<br />
''System: '''Local Backups''' > '''Status''' > Commit Changes: Simulate a commit [_]<br />
''System: '''Local Backups''' > '''Config''' > System Info: Media for Commit > usb''<br />
''System: '''Local Backups''' > '''Config''' > Edit Included Files: Included item(s)<br />
''System: '''Logfiles''' > '''Status''' > /var/log/messages: '''Tail'''</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Writing_User_Documentation_for_ACF&diff=2820Writing User Documentation for ACF2009-05-29T20:04:28Z<p>Aalatchm: Created page with '= Guidelines on Writing User Documentation for ACF = Many users of Alpine Linux devices may use only the ACF Web interface. == Basic suggestions == *Write names and labels ''as...'</p>
<hr />
<div>= Guidelines on Writing User Documentation for ACF =<br />
<br />
Many users of Alpine Linux devices may use only the ACF Web interface.<br />
<br />
== Basic suggestions ==<br />
*Write names and labels ''as they appear in ACF'', such as "DNScache" instead of dnscache.<br />
*Avoid using extra nouns such as "menu option," "tab," "section," etc. for simplicity. The formatting below should be sufficient.<br />
<br />
== Formatting ==<br />
<br />
Here is an example of the suggested formatting:<br />
<br />
<br />
''System: '''Local Backups''' > '''Config''' > System Info: Media for Commit''<br />
<br />
When describing an page or procedure in ACF, user documentation may refer to items such as: <br />
*menu choices<br />
*tabs<br />
*section headings<br />
*buttons<br />
*links<br />
*check boxes<br />
*fields</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Alpine_local_backup&diff=2814Alpine local backup2009-05-22T21:55:45Z<p>Aalatchm: added "Multiple Backups" section</p>
<hr />
<div>= Alpine local backups =<br />
Alpine itself only holds some few required packages when you boot a clean Alpine Linux.<BR><br />
But you probably want to do some personal adjustments (e.g [[Alpine_package_management|installing a package]] or doing some configuration).<BR><br />
Because Alpine runs on RAM, and everything in RAM will get lost next time the box is rebooted or shut down, so you need to permanently save your modifications and adjustments to Alpine. This is where 'lbu' comes in handy!<br />
<br />
First thing you need to know is this: '''As default 'lbu' only cares about modifications in ''/etc/'' and it's subfolders!'''<BR><br />
Please have a look at '[[#Include_special_files.2Ffolders_to_the_apkovl|lbu include]]' to save files/folders located elsewhere than in ''/etc/''.<br />
<br />
Alpine has the following tools for permanently storing your modifications:<br />
* lbu<br />
* lbu_commit ''(Same as 'lbu commit')''<br />
* lbu_exclude ''(Same as 'lbu exclude')''<br />
* lbu_include ''(Same as 'lbu include')''<br />
* lbu_status ''(Same as 'lbu status')''<br />
* lbu_update ''(Same as 'lbu update')''<br />
<br />
In the below examples you will have some charactes with special meaning<br />
* '''|''' = '''or''' ''('lbu commit|ci' means that you can type ether 'lbu commit' or 'lbu ci')''<br />
* '''[ ]''' = '''optional''' ''(In 'lbu commit|ci [-nv]' you can just skip the '-n', '-v' or '-nv' part if you don't want it)''<br />
<br />
== Saving your changes ==<br />
When you save your changes you will get a file that is named like 'myboxname.apkovl.tar.gz' ''('myboxname' will be the same as the hostname)''.<BR><br />
This file (that contains your modifications) is called 'apkovl'.<BR><br />
You will need to save your 'apkovl' on some suitable media (floppy, usb, cf, other).<br />
<pre><br />
usage: lbu commit|ci [-nv] [<media>]<br />
<br />
Options:<br />
-d Remove old apk overlay files.<br />
-e Protect configuration with a password.<br />
-n Don't commit, just show what would have been commited.<br />
-p <password> Give encryption password on the command-line<br />
-v Verbose mode.<br />
<br />
The following values for <media> is supported: floppy usb<br />
If <media> is not specified, the environment variable LBU_MEDIA will be used.<br />
<br />
Password protection will use aes-256-cbc encryption. Other ciphers can be<br />
used by setting the DEFAULT_CIPHER or ENCRYPTION environment variables.<br />
For possible ciphers, try: openssl -v<br />
<br />
The password used to encrypt the file, can either be specified with the -p<br />
option or using the PASSWORD environment variable.<br />
<br />
The environment varialbes can also be set in /etc/lbu/lbu.conf<br />
</pre><br />
<br />
== Include special files/folders to the apkovl ==<br />
Assume that you have some files that you want to permanently save, but they are located somewhere else than in ''/etc/''.<BR><br />
It could be ''/root/.ssh/authorized_keys'' (used by 'sshd' to authenticate ssh-users).<BR><br />
Such files/folders can be added to the ''/etc/lbu/include'' list by manually editing the file or using the following command:<br />
<pre><br />
usage: lbu include|inc|add [-rv] <file> ...<br />
lbu include|inc|add [-v] -l<br />
<br />
Options:<br />
-l List contents of include list.<br />
-r Remove specified file(s) from include list instead of adding.<br />
-v Verbose mode.<br />
</pre><br />
'''''Note:''' This command only modifies some lbu-related configfiles. You will need to run 'lbu commit' to actually create/modify your apkovl.''<br />
<br />
== Exclude specific files/folders from the apkovl ==<br />
Assume that you have some files located in ''/etc/'' or one of it's subfolders that you '''do not''' want to permanently save.<BR><br />
It could be some logfile or statusfile that for some reason is elsewhere than in ''/var/log''.<BR><br />
Such files/folders can be added to the ''/etc/lbu/exclude'' list by manually editing the file or using the following command:<br />
<pre><br />
usage: lbu exclude|ex|delete [-rv] <file> ...<br />
lbu exclude|ex|delete [-v] -l<br />
<br />
Options:<br />
-l List contents of exclude list.<br />
-r Remove specified file(s) from exclude list instead of adding.<br />
-v Verbose mode.<br />
</pre><br />
'''''Note:''' This command only modifies some lbu-related configfiles. You will need to run 'lbu commit' to actually create/modify your apkovl.''<br />
<br />
== Check what will be added to your apkovl ==<br />
Sometimes it would be handy to know what files will be permanently saved next time you run 'lbu commit'. Here you have your help:<br />
usage: lbu list|ls<br />
<br />
== Create a apkovl elsewhere than on some specific media ==<br />
<br />
<pre><br />
usage: lbu package|pkg -v [<dirname>|<filename>]<br />
<br />
Options:<br />
-v Verbose mode.<br />
<br />
If <dirname> is a directory, a package named <hostname>.apkovl.tar.gz will<br />
be created in the specified directory.<br />
<br />
If <filename> is specified, and is not a direcotry, a package with the<br />
specified name willbe created.<br />
<br />
If <dirname> nor <filename> is not specified, a package named<br />
<hostname>.apkovl.tar.gz will be created in current work directory.<br />
</pre><br />
<br />
== Check what files have been changed since last commit ==<br />
<pre><br />
usage: lbu status|st [-M <MASK>] [-av]<br />
<br />
Options:<br />
-M Use a different mask for comparing. (see sfic -h)<br />
-a Compare all files, not just since last commit.<br />
-v Also show include and exclude lists.<br />
</pre><br />
<br />
== Multiple Backups ==<br />
Lbu can now keep backups so you can revert to older, good known config.<br />
Set BACKUP_LIMIT in /etc/lbu/lbu.conf to the number of backups you want<br />
to keep.<br />
<br />
You can list the current backups with:<br />
<br />
lbu list-backup [<media>]<br />
<br />
and you can revert to an older with:<br />
<br />
lbu revert <filename> [<media>]<br />
<br />
Note that when you revert, the current apkovl on media will be backed<br />
up.</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Replacing_a_package&diff=2707Replacing a package2009-04-21T20:40:22Z<p>Aalatchm: new page with basic steps</p>
<hr />
<div>== How to Replace a Package in Alpine 1.7.x and 1.8.x ==<br />
# Log in as root to the command-line console.<br />
# cd YOUR_ALPINE_MEDIUM/apks<br />
# wget http://dev.alpinelinux.org/alpine/v1.8/apks/PACKAGE_NAME.apk<br />
# rm OLD_PACKAGE_NAME.apk<br />
# md5sum *.apk | sort -k 2 | gzip > INDEX.md5.gz<br />
# apk_fetch -u<br />
# Stop any associated services<br />
# apk_delete -f PACKAGE_NAME<br />
# apk_add -f PACKAGE_NAME<br />
# Start any associated services.</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Alpine_Linux:Documentation&diff=2442Alpine Linux:Documentation2008-11-03T21:36:52Z<p>Aalatchm: </p>
<hr />
<div>== User Documentation ==<br />
Documentation how to install and use the Alpine distro.<br />
<br />
* [[Installing Alpine]]<br />
* [[Upgrading Alpine]]<br />
* [[Alpine package management]]<br />
* [[Comparison with Gentoo and Debian]]<br />
* Submitting [[Problem Reports]]<br />
<br />
=== HOWTOS ===<br />
<br />
==== Installation ====<br />
* [[Bootstrapping Alpine on Soekris net4xxx]]<br />
* [[Bootstrapping Alpine on PC Engines ALIX.3]]<br />
* [[Setting up a software raid1 array]]<br />
* [[Setting up Logical Volumes with LVM]]<br />
* [[Setting up a /var partition on software IDE raid1]]<br />
* [[Native Harddisk Install]]<br />
* [[Installing XUbuntu using Alpine boot floppy]]<br />
<br />
==== Networking ====<br />
* [[Setting up a OpenVPN-server with Alpine]]<br />
* [[Setting up traffic monitoring using rrdtool (and snmp)]]<br />
* [[Setting up Zaptel/Asterisk on Alpine]]<br />
* [[Using HSDPA modem]]<br />
* [[Using Alpine on Windows domain with IPSEC isolation]]<br />
<br />
==== Misc ====<br />
* [[Setting up lm_sensors]]<br />
* [[Setting up Satellite Internet Connection]]<br />
* [[Setting up Streaming an Asterisk Channel]]<br />
* [[Formatting HD/Floppy/Other]]<br />
* [[Setting up Transmission (bittorrent) with Clutch WebUI]]<br />
* [[Protecting your email server with Alpine]]<br />
* [[Hosting Web/Email services on Alpine]]<br />
* [[Running Alpinelinux As a QEMU networked Guest ]]<br />
<br />
==== iSCSI ====<br />
* [[iSCSI Target and Initiator Configuration]]<br />
* [[iSCSI Raid and Clustered File Systems]]<br />
<br />
=== Vserver ===<br />
* [[Setting up a basic vserver]]<br />
<br />
== Developer Documentation ==<br />
Documentation how to build and modify the Alpine distro.<br />
<br />
* [[Alpine Package Testing Suite]]<br />
* [[Setting up the build environment]]<br />
* [[Newbie Guide to Building an apk]]<br />
* [[Creating patches]]<br />
* [[Alpine Configuration Framework Design]] (Why ACF is the way it is)<br />
* [[Development using git]]<br />
<br />
== Misc. References ==<br />
Other useful references.<br />
<br />
* http://www.metoffice.gov.uk/research/nwp/external/fcm/doc/user_guide/working_practices.html - Some guidelines on use of Trac and SVN</div>Aalatchmhttps://wiki.alpinelinux.org/w/index.php?title=Development_using_git&diff=2441Development using git2008-11-03T21:34:27Z<p>Aalatchm: /* Development using git */</p>
<hr />
<div>Git is now being used for version control of the '''alpine-baselayout''' and '''alpine-conf''' packages.<br />
<br />
== Git Clone ==<br />
<br />
To get started, clone the git repository for the package you are interested in:<br />
<br />
git clone git://dev.alpinelinux.org/alpine-baselayout<br />
git clone git://dev.alpinelinux.org/alpine-conf</div>Aalatchm