📜 ⬆️ ⬇️

Easy and easy: mail and jabber for users of your site

Let's say you develop a website on the Internet. You have regular users, someone comes to you from time to time. And of course you are looking for ways to keep the audience on your site, inventing all sorts of original features and perfecting the interface. Why not use your site name as an export coin? After all, you can provide your users with an additional bonus mailing address and the corresponding Jabber address in your domain.

Of course, I do not suggest becoming the next mail provider. It's stupid when there are players like gmail.com and yandex.ru . In addition, you can naturally use the services of the aforementioned Google and Yandex to connect your domain to their services. But then you will not get any integration with your user base and no control over the available functionality.

But there is a simple and elegant way to transparently combine mail and Jabber in your domain with user profiles on the site. A user will have a single login and a single password everywhere, and there will be no need to perform any additional actions to connect mail and a Jabber account. Just an extra bonus, complete with registration on your portal.

Let's start with a description of how this will work. If you have a website on which you can register, then you certainly have a database of users with a login, email address and password for each (if you value your users just a little, then instead of passwords you will have irreversible hashes, but for this article it does not matter). In addition, the logins for all users are of course different. Then you can configure the mail server , which will redirect mail for user@yourdomain.com to the main mailbox of the user from the profile, as well as the Jabber server , which will be authorized by JID user@yourdomain.com through your database. Thus, users of your site will receive a postal and Jabber address in your domain, combined with their profile. In this case, you will not provide the mailbox, only the address. This is very convenient for the end user, since he always has a box somewhere and usually doesn’t make sense to start another one. But the beautiful address, which can boast, never hurts. The only thing that is necessary is to provide for the possibility of disabling this functionality through the user profile. Otherwise, such a system can be very effectively used to send spam.
')

The practical side of the issue


Let's move from theory to practice. To raise mail and Jabber services, you will need any Linux server, but this article describes Ubuntu Server 10.04 . In addition, all instructions will be similar for older versions of Ubuntu , as well as for Debain .

As a mail server, it makes sense to use Postfix , as one of the most reliable and undemanding to resources. As XMPP (aka Jabber), the server is ejabberd . These two servers will be virtually unrelated to each other, so let's start by setting up mail.

Mail system setup


To install Postfix in Ubuntu, just run

sudo apt-get install postfix 

When you are asked what type of settings to use - select the website and enter any data in response to further questions from the bald, just below there will be a ready config with all the necessary settings.

After installation, you need to configure Postfix so that when you request delivery of a letter to someuser@yourdomain.com , Postfix would look in your database, find out if the user you are looking for is there and if the mailing address is activated for it, - to what address to redirect the letter. After that, Postifx must accept the letter and redirect it to the primary email address of the specified user.

This problem can be solved using Postfix built-in tools, but forcing a mail server for each new letter to send a request to the main database is not a good idea, since it will put an extra load on your user database, since spam is now a lot of spamming on the Internet. It is much better to upload the necessary information a couple of times a day from your main database to Postfix, since all this information is a table of two fields: the name of the user and his main email address.

To redirect mail to Postfix, use different alias_maps . Since the described system is not tied to the system users of the server, we will use the virtual domains mechanism and the virtual_alias_maps parameter to redirect mail to the main addresses of users. In this parameter, you just need to specify the table of correspondence of the user's address to the address to which the correspondence should be redirected. This table will be created based on the contents of your main user database with a special script, about which just below.

In the meantime, let's finally deal with the necessary Postfix options. All Postfix configuration is done by editing the /etc/postfix/main.cf configuration file. So, to solve the task, as I said, the virtual domains mechanism will be used, since real mail users on the server are not from where to come from. Therefore, you must completely disable local delivery. In addition, users should not have any access to your SMTP server, so you should disable authentication and SSL encryption.

Here is the contents of the configuration file that is used on one of my servers:

 # See /usr/share/postfix/main.cf.dist for a commented, more complete version ######################################################## ##   smtpd_banner = $myhostname ESMTP server biff = no #   .    10Mb message_size_limit = 204800000 #    myhostname = mail.yourdomain.com myorigin = $mydomain mynetworks = 127.0.0.0/8 mailbox_size_limit = 0 virtual_mailbox_limit = 0 recipient_delimiter = + inet_interfaces = all inet_protocols = ipv4 append_dot_mydomain = no readme_directory = no ########################################################## ##     #    ,     mydestination = local_recipient_maps = relay_domains = relay_recipient_maps = transport_maps = #    virtual_mailbox_domains = $mydomain #    (  -   Dovecot) #      (  ) virtual_mailbox_maps = hash:/etc/postfix/mailboxes/local-mailboxes #    virtual_alias_maps = hash:/etc/postfix/mailboxes/db-aliases hash:/etc/postfix/mailboxes/local-aliases #   .   ,    Dovecot virtual_mailbox_base = /var/mail virtual_uid_maps = static:900 virtual_gid_maps = static:900 ########################################################### ##    -  # SASL   smtpd_sasl_auth_enable = no # TLS  smtpd_use_tls = no ########################################################### ##    #  ETRN  smtpd_etrn_restrictions = reject #  VRFY  disable_vrfy_command = yes #   EHLO (HELO)  smtpd_helo_required = yes #        smtpd_reject_unlisted_recipient = yes #    -     PTR (  ) smtpd_client_restrictions = permit_mynetworks reject_unknown_reverse_client_hostname permit #   HELO.     ,      smtpd_helo_restrictions = permit_mynetworks reject_invalid_helo_hostname reject_non_fqdn_helo_hostname reject_unknown_helo_hostname permit #   MAIL FROM.   ,      smtpd_sender_restrictions = reject_non_fqdn_sender reject_unknown_sender_domain permit #   RCPT TO.       smtpd_recipient_restrictions = reject_non_fqdn_recipient reject_unlisted_recipient permit_mynetworks reject_unauth_destination permit #   .       smtpd_data_restrictions = reject_unauth_pipelining 

You can read more about the configuration and various Postfix options on the Internet, for our task there are three important points:
  1. Do not put too hard restrictions to filter spam. Leave this prerogative to the mail servers your users use. Your task is to simply send mail and weed out only that spam is 100%. You can read more about correctly configuring Postfix to minimize spam flow in one of my previous articles . Please note, for normal forwarding, you need to remember to properly configure the DNS records for your server, you can also read about this in the article at the link.
  2. Be sure to specify an empty local user map in the virtual_mailbox_maps parameter, otherwise Postfix will accept mail for all addresses in your domain and give a bunch of errors about undeliverable. In my case, the map file is / etc / postfix / mailboxes / local-mailboxes . This is a plain empty text file. After creating it, you must run the command

     sudo postmap /etc/postfix/mailboxes/local-mailboxes 

    otherwise, Postfix will not work with your file.
  3. Finally, all redirection rules will be defined in two files specified in the virtual_alias_maps parameter. One will be created automatically by the script based on the contents of your user database, and the second is needed to manually create additional auxiliary addresses. After editing the file of additional addresses, do not forget to issue the postmap command for it. More information about the use of aliases to redirect mail to Postfix can be found in the official documentation .
Now, in fact, the script itself, which creates a map of aliases based on the contents of the user database. The following script is designed to work with the database engine SMF , you will need to modify it for your database:

 #!/usr/bin/perl #    SMF    , #        postfix.    # cron.   /etc/cron.d/postfix-smf-sync use 5.010; use DBI; ############################################################# #    (MySQL) $MYSQL_host = 'bd.yourdomain.com'; $MYSQL_port = '3306'; $MYSQL_user = 'postfix'; $MYSQL_pass = 'PASSW0RD'; $MYSQL_db = 'my_smf'; #  SMF -          $SMF_GID = '15'; $SMF_prefix = 'smf_'; #   $domain = "yourdomain.com"; #   $postfix_file = "/etc/postfix/mailboxes/db-aliases"; ############################################################# $dbh = DBI->connect("DBI:mysql:$MYSQL_db:$MYSQL_host:$MYSQL_port",$MYSQL_user,$MYSQL_pass) or die "Hey guys! We've got a big error here...\n"; #   my $sth = $dbh->prepare("SELECT memberName, realName, emailAddress FROM ${SMF_prefix}members WHERE (ID_GROUP = $SMF_GID OR FIND_IN_SET($SMF_GID, additionalGroups))") or die "Hey guys! We've got big error here!\n"; $sth->execute() or die "Hey guys! We've got a big error here...\n"; #     Postfix open ALIASES, ">$postfix_file" or die "Can't open $postfix_file\n"; say ALIASES <<INTRO; ################################################# #    yourdomain.com  # #  . # # # #      # # /etc/postfix/scripts/postfix-sync.pl # #      SMF.  # #    . # ################################################# INTRO #     : #   $w = '[a-zA-Z0-9]'; #  -: $s = '[._\-]'; #   while (my $row = $sth->fetchrow_hashref()) { #  lower case,       my $user = lc $row->{realName}; #       -   #   ,    ".", "-"  "_" next unless $user =~ /^($w+$s)*$w+$/; # ,     my $email = lc $row->{emailAddress}; next if "$user\@$domain" eq $email; #     say ALIASES "$user\@$domain\t$row->{emailAddress}"; } #        postfix' close ALIASES; `/usr/sbin/postmap hash:$postfix_file`; 

As a result of the script operation, the alias file / etc / postfix / mailboxes / db-aliases will be created, in which there will be lines like

 someuser@yourdomain.com usermail@anotherdomain.com 

One line for each user in the mail user group. The script contains a fool check: first, no users with special characters in the name will be skipped in the Postfix alias file. Well, secondly, the user will not be able to specify the address on your website as the main address in his profile, so that the postal system does not turn out to be a cycle.

All that is left to do is to add the launch of the script to the scheduler, for example, create a cron job. To do this, create a file /etc/cron.d/postfix-sync with something like the following:

 # Synchronize Postfix with BD 18 04 * * * root /etc/postfix/scripts/postfix-sync.pl 

As you can see, my script runs every day at 04:18.

This completes the postal system configuration.

Setup XMPP server


We will use ejabberd as XMPP server. First you need to put it:

 sudo apt-get install ejabberd 

The Internet is full of ejabberd configuration materials, all we need to do to integrate with the existing user database is to tell ejabberd to use an external authorization mechanism and write a module that implements authorization through our database. To use external authorization, you need to write only two lines in the ejabberd configuration file /etc/ejabberd/ejabberd.conf :

 {auth_method, external}. {extauth_program, "/etc/ejabberd/auth.pl"}. 

Well, actually the authorization module itself for the same SMF database, which you will need to change for your database:

 #!/usr/bin/perl use 5.010; use Digest::SHA1 qw(sha1_hex); use DBI; ############################################################# #    (MySQL) $MYSQL_host = 'bd.yourdomain.com'; $MYSQL_port = '3306'; $MYSQL_user = 'postfix'; $MYSQL_pass = 'PASSW0RD'; $MYSQL_db = 'my_smf'; #  SMF -          $SMF_GID = '15'; $SMF_prefix = 'smf_'; #   $valid_domain = "yourdomain.com"; ############################################################# #     sub db_connect { my $dbh = DBI->connect("DBI:mysql:$MYSQL_db:$MYSQL_host:$MYSQL_port",$MYSQL_user,$MYSQL_pass); return $dbh; } $dbh = db_connect; #   ,   .  , . while(1) { #    ejabberd my $nread = sysread STDIN, my $buf, 2; unless ($nread == 2) { exit } my $len = unpack "n", $buf; $nread = sysread STDIN, $buf, $len; my ($op,$user,$domain,$passwd) = split /:/, $buf; #   ,    $passwd =~ s/[\n\r]//g; #   ejabberd,     die "_" if $valid_domain ne $domain; my $result = 0; ##      : #       -   #   ,    ".", "-"  "_" if ($user =~ /^\w+[\w.\-_]*\w+$/) { #   ,    unless ($dbh) { $dbh = db_connect } #     .   -   my $sth = $dbh->prepare("SELECT memberName, realName, passwd FROM ${SMF_prefix}members WHERE (ID_GROUP = $SMF_GID OR FIND_IN_SET($SMF_GID, additionalGroups)) AND realName = '$user'") or $dbh = undef if $dbh; #     .   -   $sth->execute() or $dbh = undef if $dbh; #     if ($dbh) { #     my $num = $sth->rows(); #          my $row = $sth->fetchrow_hashref() if $num == 1; #     if ($op =~ /auth/i and $num == 1) { my $epass = sha1_hex(lc($row->{memberName}) . $passwd); $result = $epass eq $row->{passwd} ? 1 : 0; } elsif ($op =~ /isuser/i and $num == 1) { $result = exists $row->{memberName} ? 1 : 0; } } } else { $result = 0; } #    ejabberd my $out = pack "nn", 2, $result; syswrite STDOUT, $out; } 

In addition, you should remove the mod_register module from the modules section of the ejabberd configuration file, since it is impossible to register on your Jabber server.

The rest of the Jabber server setting is not tied to authorization. Accordingly, you can freely configure conferences, logging, and other features that are abundantly available in ejabberd , in order to get the XMPP server that best suits your needs.

As a summary


The proposed technical solution makes it easy to provide your users with email and XMPP addresses in your domain, while the user is not required to register and remember any additional passwords and logins. The address is turned on and off in the user profile with one tick (or something else, depending on the implementation).

In this case, the user receives a full-featured XMPP account with all the additional services that you only want to provide him. And a mailing address that is not tied to any particular physical mailbox. By the way, I pay attention: the user can send mail from the issued address without any problems, though not through your SMTP server. For example, sending on behalf of a third-party mailbox is implemented in Gmail, or you can use the provider’s SMTP server.

On the technical side, uploading addresses for Postfix from your main database negates the danger of the main site crashing due to mail problems. Problems with XMPP should also not arise, since in fact the XMPP server is practically not connected with other services. The authorization module simply checks the password sent via an encrypted connection (an XMPP feature) through the base, without changing or adding anything. So through him something bad to do too will not work.

The only problem with the proposed scheme is the theoretical possibility of compromising the user's main mailbox by sending a special letter that your server accepts, but rejects the user's mail server. In this case, the sender will receive a breakdown in which the main address of the user will be written. And although it is usually easy to find out the mailing address using more simple methods, you only need to enable mail for your domain only at the user's request, so as not to paranoid paranoids.

So, easily and naturally, you can try to catch up and overtake Vkontakte and Facebook. The described scheme actually works on several sites for quite a long time. Any comments, questions and suggestions are greatly appreciated!

Current version of the article


The latest and most current version of this article, divided into two parts - for mail and Jabber , is on the official Russian-language Wiki-resource documentation on Ubuntu. There you can freely improve and supplement the laid out reference and training materials, as well as add your own. If you have something to tell other Ubuntu users, then a huge request - write or edit the relevant article on help.ubuntu.ru . Even with small improvements and additions you will help thousands of people, and some of them, in turn, will describe something useful and interesting for you.

Source: https://habr.com/ru/post/104741/


All Articles