簡単で簡単:サイトのユーザー向けのメールとJabber

インターネットでWebサイトを開発しているとします。 通常のユーザーがいて、誰かが時々あなたのところに来ます。 そしてもちろん、あなたはあなたのサイトで視聴者を維持し、あらゆる種類のオリジナルの機能を発明し、インターフェースを輝かせる方法を探しています。 サイトの名前を輸出コインとして使用してみませんか? 追加ボーナスとして、ドメイン内のメールアドレスと対応するJabberアドレスをユーザーに提供できます。

もちろん、私は次のメールプロバイダーになることを提案しません。 gmail.comyandex.ruのようなプレーヤーがいる場合、これは愚かです 。 さらに、前述のGoogleとYandexのサービスを自然に使用して、ドメインをサービスに接続できます。 ただし、ユーザーベースとの統合や、利用可能な機能の制御はできません。

ただし、ドメイン内のメールとJabberをサイトのユーザープロファイルと透過的に結合するシンプルでエレガントな方法があります。 この場合、ユーザーは常に単一のログインと単一のパスワードを持ち、メールとJabberアカウントを接続するために追加のアクションを実行する必要はありません。 ポータルへの登録が完了するだけの追加ボーナス。

これがどのように機能するかを説明することから始めましょう。 登録できるサイトがある場合は、もちろん、それぞれにユーザー名、電子メールアドレス、パスワードを持つユーザーデータベースがあります(少しでもユーザーを評価する場合は、パスワードの代わりに元に戻せないハッシュがありますが、この記事では関係ありません)。 さらに、すべてのユーザーのログインはもちろん異なります。 次に、 メールサーバーを設定します。 メールサーバーuser@yourdomain.comにメールをプロファイルからユーザーのメインメールボックスにリダイレクトし、 Jabberサーバーuser@yourdomain.com JIDによってデータベースを介して認証します。 したがって、サイトのユーザーは、プロファイルと組み合わせて、ドメイン内のメールとJabberアドレスを受け取ります。 ただし、メールボックスは提供せず、アドレスのみを提供します。 これはエンドユーザーにとって非常に便利です。エンドユーザーは常にどこかにボックスを持っているため、通常は別のボックスを起動しても意味がありません。 しかし、誇りに思う美しいアドレスは、決して痛いことはありません。 指定する必要があるのは、ユーザープロファイルを介してこの機能を無効にすることだけです。 それ以外の場合、このようなシステムはスパムを送信するために非常に効果的に使用できます。

問題の実際的な側面


理論から実践に移りましょう。 メールおよびJabberサービスをアップグレードするには、Linuxサーバーが必要ですが、この記事ではUbuntu Server 10.04について説明します 。 さらに、古いバージョンのUbuntuDebainのすべての手順は同様です。

最も信頼性が高く、同時にリソースを必要としないメールサーバーとしてPostfixを使用するのは理にかなっています。 XMPP(別名Jabber)として、サーバーはejabberdです。 これらの2つのサーバーは実質的に相互接続されないため、メールのセットアップから始めましょう。

メールシステムのセットアップ


Ubuntuに Postfixをインストールするには単に実行します

sudo apt-get install postfix 

使用する設定の種類を尋ねられたら、ウェブサイトを選択し、ブルドーザーからのさらなる質問に応じていくつかのデータを入力します。すぐ下に、必要なすべての設定を含む既製の設定があります。

インストール後、メッセージをsomeuser@yourdomain.com送信するように要求するときにPostfixがデータベースを調べて、探しているユーザーがそこにいるかどうか、郵送先住所が有効になっているかどうか、すべてが正常かどうかを確認するように、Postfixを構成する必要があります-レターをリダイレクトするアドレス。 その後、Postifxはレターを受け入れ、指定されたユーザーのメインの住所にリダイレクトする必要があります。

この問題は組み込みのPostfixツールで解決できますが、メールサーバーが新しいレターごとにメインデータベースにリクエストを送信するように強制することは良い考えとはほど遠いです。これは現在インターネット上に多くのスパムがあるため、ユーザーデータベースに余分な負荷をかけるからです。 この情報はすべて、ユーザー名とそのメインメールアドレスの2つのフィールドのテーブルであるため、必要な情報をPostfixのメインデータベースから1日に数回アンロードすることをお勧めします。

Postfix さまざまなalias_maps使用してメールをリダイレクトします。 説明したシステムはサーバーのシステムユーザーとはまったく関係ないため、仮想ドメインメカニズムとvirtual_alias_mapsパラメーターを使用して、メールをメインユーザーアドレスにリダイレクトします。 このパラメーターでは、ユーザーのアドレスと通信のリダイレクト先のアドレスの対応表を指定するだけです。 このテーブルは、以下で説明する特別なスクリプトを使用して、メインユーザーデータベースの内容に基づいて作成されます。

それまでの間、最後に必要なPostfixオプションを見つけましょう。 すべてのPostfix設定は、設定ファイル/etc/postfix/main.cfを編集することにより行われます。 したがって、タスクを解決するために、先ほど言ったように、仮想ドメインメカニズムが使用されます。これは、サーバー上の実際のメールユーザーには取得先がないためです。 したがって、ローカル配信を完全に無効にする必要があります。 また、ユーザーはSMTPサーバーにアクセスできないようにする必要があるため、認証とSSL暗号化を無効にする必要があります。

以下は、私のサーバーの1つで使用される構成ファイルの内容です。

 # 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 

インターネット上のPostfixの設定とさまざまなオプションについて詳しく読むことができますが、私たちのタスクには3つのポイントが重要です。
  1. スパムをフィルタリングするために、厳しすぎる制限を設けないでください。 これは、ユーザーが使用するメールサーバーに対する特権です。 あなたの仕事は、単にメールを転送し、スパムが100%であることだけを除外することです。 私の過去の記事の 1つでスパムの流れを最小限に抑えるために、Postfixの適切な構成について詳しく読むことができます。 通常の転送では、サーバーのDNSレコードを正しく構成することを忘れないでください。これについては、こちらの記事をご覧ください。
  2. virtual_mailbox_mapsパラメーターで空のローカルユーザーカードを指定してください。そうしないと、Postfixはドメイン内のすべてのアドレスのメールを受信し、配信エラーに関する大量のエラーを出します。 私の場合、マップファイルは/ etc / postfix / mailboxes / local-mailboxesと呼ばれます。 これはプレーンな空のテキストファイルです。 作成後、コマンドを実行する必要があります

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

    そうしないと、Postfixはファイルを操作できません。
  3. 最後に、すべてのリダイレクトルールは、 virtual_alias_mapsパラメーターで指定された2つのファイルに設定されます。 1つはユーザーベースのコンテンツに基づいてスクリプトによって自動的に作成され、2つ目は追加の補助アドレスを手動で作成するために必要です。 追加のアドレスのファイルを編集した後、そのファイルに対してpostmapコマンドを実行することを忘れないでください。 エイリアスを使用してPostfixのメールをリダイレクトする方法の詳細については、 公式ドキュメントをご覧ください。
実際、スクリプト自体は、ユーザーベースのコンテンツに基づいてエイリアスのマップを作成します。 以下のスクリプトは、データベースエンジンSMFと連携するように設計されています。データベースに合わせて変更する必要があります。

 #!/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`; 

スクリプトの結果として、エイリアスファイル/ etc / postfix / mailboxes / db-aliasesが作成され、その中に次の形式の行があります。

 someuser@yourdomain.com usermail@anotherdomain.com 

メールユーザーグループの各ユーザーごとに1行。 このスクリプトには、愚か者のチェックが含まれています。まず、名前に特殊文字が含まれているユーザーはPostfixエイリアスファイルにスキップされません。 次に、ユーザーは自分のプロファイルのメインアドレスとしてサイトのアドレスを指定できないため、メールシステムサイクルが機能しません。

あとは、スケジューラにスクリプト実行を追加するだけです(たとえば、 cronタスクを作成します)。 これを行うには、次の内容で/etc/cron.d/postfix-syncファイルを作成します。

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

ご覧のとおり、私のスクリプトは毎日04:18に実行されます。

これで、メールシステムのセットアップが完了しました。

XMPPサーバーを構成する


ejabberdをXMPPサーバーとして使用します。 最初にそれを置く必要があります:

 sudo apt-get install ejabberd 

インターネットにはejabberdのセットアップに関する資料がたくさんありますが、既存のユーザーデータベースと統合するは、外部認証メカニズム使用し、データベースを介して認証を実装するモジュールを記述するようにejabberdに指示するだけです。 設定ファイルejabberd /etc/ejabberd/ejabberd.confで外部認証を使用するには、次の2行のみを記述する必要があります。

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

実際、同じSMFデータベースの承認モジュール自体は、データベースに合わせて変更する必要があります。

 #!/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; } 

さらに、Jabberサーバーに登録することは不可能であるため、 ejabberd構成ファイルのモジュールセクションからmod_registerモジュールを削除する価値があります。

残りのJabberサーバーのセットアップは、いかなる方法でも許可に関係していません。 したがって、 ejabberdで豊富に利用できる会議、ロギング、およびその他の機能を自由に構成できるため、最終的にタスクに最適なXMPPサーバーを取得できます。

まとめとして


提案された技術的ソリューションにより、ユーザーはドメイン内の電子メールアドレスとXMPPアドレスを簡単に提供でき、ユーザーは追加の登録や追加のパスワードとログインを覚える必要がありません。 アドレスは、ユーザープロファイルで1ティック(または実装に応じて他の何か)でオンとオフを切り替えられます。

この場合、ユーザーは完全に機能するXMPPアカウントを受け取りますが、XMPPアカウントには、提供したいすべての追加サービスが含まれています。 また、特定の物理メールボックスに関連付けられていない住所。 ところで、私は注意を引きます。ユーザーは、SMTPサーバー経由ではなくても、問題なく発行されたアドレスからメールを送信できます。 たとえば、サードパーティのメールボックスに代わって送信することはGmailに実装されていますが、プロバイダーのSMTPサーバーを使用することもできます。

技術面では、メインデータベースからPostfixのアドレスをアンロードすると、メールの問題によりメインサイトがクラッシュする危険性がなくなります。 XMPPサーバーは本質的に他のサービスに接続されていないため、XMPPの問題も発生しないはずです。 認証モジュールは、何も変更したり追加したりすることなく、データベースを介して暗号化された接続(XMPP機能)を介して送信されたパスワードをチェックするだけです。 そのため、悪いこともできません。

提案されたスキームの唯一の問題は、サーバーがユーザーのメールサーバーを受け入れるが拒否する特殊な文字を送信することにより、ユーザーのメインメールボックスを侵害する理論的な可能性です。 この場合、送信者は、ユーザーのメインアドレスが書き込まれる内訳を受け取ります。 そして、より簡単な方法を使用して郵送先を見つけることは通常困難ではありませんが、偏執病に悩まされないように、ユーザーのリクエストでのみドメインのメールを有効にする必要があります。

そのため、簡単かつ自然に、VkontakteとFacebookに追いつくことができます。 説明されたスキームは、かなり長い間、いくつかのサイトで実際に機能します。 コメント、質問、提案は大歓迎です!

記事の実際のバージョン


この記事の最新の最新バージョンは、 メールJabberの 2つの部分に分かれており、Ubuntuの公式ロシア語版Wikiリソースドキュメントにあります。 そこで、レイアウトされた参照資料やトレーニング資料を自由に改善および補足したり、独自の資料を追加したりできます。 他のUbuntuユーザーに伝えたいことがあれば、膨大なリクエスト-help.ubuntu.ruの対応する記事を書いたり編集したりしてください わずかな改善や追加があったとしても、何千人もの人々を支援し、そのうちの1人が有用で興味深い何かを説明します。

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


All Articles