GoogleApps + Postfix + Fetchmail(OpenLdap + Postfix)

背景

実装

プラットフォーム
AltLinux 4、カーネルバージョン2.6.18-std-smp-alt6。 すべてのパッケージは公式リポジトリからインストールされました。
LDAPサーバーをインストールする
パッケージopenldap-servers-2.3.35-alt0、libldap2.3-2.3.35-alt0、openldap-clients-2.3.35-alt0、openldap-2.3.35-alt0、openldap-doc-2.3.35-alt0をインストールします。
/etc/openldap/slapd.confファイルに追加のスキームを含めます。
include /etc/openldap/schema/core.schema
include /etc/openldap/schema/cosine.schema
include /etc/openldap/schema/inetorgperson.schema
include /etc/openldap/schema/openldap.schema
include /etc/openldap/schema/nis.schema
include /etc/openldap/schema/courier.schema
include /etc/openldap/schema/qmail.schema
allow bind_v2
concurrency 20
gentlehup on
sizelimit -1
password-hash {CLEARTEXT}
pidfile /var/run/slapd.pid
argsfile /var/run/slapd.args
replica-pidfile /var/run/slurpd.pid
replica-argsfile /var/run/slurpd.args
rootDSE /etc/openldap/rootdse.ldif
access to dn.exact=""
by * read
access to dn.subtree="cn=Subschema"
by * read
access to attrs=userPassword
by self write
by anonymous auth
by * none
modulepath /usr/lib/openldap
moduleload back_hdb.la
moduleload back_monitor.la
moduleload back_null.la
include /etc/openldap/slapd-hdb-db01.conf

新しいLDAPベースをslapd-hdb-db01.confに登録します。
database hdb
suffix "dc=your,dc=ru"
rootdn "cn=admin,dc=your,dc=ru"
rootpw 123
directory /var/lib/ldap/bases/your.ru
index objectClass eq
index uid pres,eq,sub
index cn pres,eq,sub,subany
access to attrs=userPassword
by self write
by anonymous auth
by * none
access to *
by dn="cn=admin,dc=your,dc=ru" write
by * read

データベースを外部に公開する予定がある場合、Ldapサーバー/ etc / sysconfig / ldapがリッスンするインターフェイスを構成します(デフォルトでは127.0.0.1):
SLAPDURLLIST="ldap://servername.your.ru/"
SLAPD_OPTIONS=""
SLURPD_OPTIONS='-t /'
デーモンを開始する:
service slapd start
その後、ベースを/var/lib/ldap/bases/your.ruに作成する必要があります
ユーザーベースを満たす
既存のドメインデータベースが既にある場合は、テキストCSVファイルにアップロードし、AWKを使用してインポート可能なldifファイルに解析することができます。 何らかの方法で、ユーザーのリストを含むテキストファイルを作成し、AWKスクリプトを使用してそれをldifに変換し、ユーザーパスワードを自動的に生成するのが最も便利です。 したがって、Ldapデータベースをバックアップするスクリプトが作成されます。 Active DirectoryからアップロードするためのCSVファイル形式の例を次に示します。
"DN","objectClass","ou","distinguishedName","instanceType","whenCreated","whenChanged","uSNCreated", "uSNChanged","name","objectGUID","objectCategory","dSCorePropagationData","cn","sn","displayName", "proxyAddresses","altRecipientBL","targetAddress","mAPIRecipient","mailNickname","internetEncoding", "legacyExchangeDN","textEncodedORAddress","mail","msExchPoliciesIncluded","msExchALObjectVersion", "msExchHideFromAddressLists","givenName","altRecipient","department","homeMTA","homeMDB", "mDBUseDefaults","userAccountControl","codePage","countryCode","pwdLastSet","primaryGroupID", "objectSid","accountExpires","sAMAccountName","sAMAccountType","showInAddressBook","userPrincipalName", "msExchHomeServerName","msExchMailboxSecurityDescriptor","msExchUserAccountControl","msExchMailboxGuid", "member","groupType","badPwdCount","badPasswordTime","lastLogoff","lastLogon","userParameters","logonCount", "lastLogonTimestamp","gPLink","gPOptions","userCertificate","adminCount","msNPAllowDialin","title", "physicalDeliveryOfficeName","telephoneNumber","initials","postOfficeBox","company","deliverAndRedirect", "memberOf","scriptPath","localPolicyFlags","operatingSystem","operatingSystemVersion", "operatingSystemServicePack","dNSHostName","servicePrincipalName","isCriticalSystemObject","location","flags", "uNCName","versionNumber","serverName","portName","driverName","priority","printStartTime","printEndTime", "printBinNames","printMaxResolutionSupported","printOrientationsSupported","printCollate","printColor", "printShareName","printSpooling","printKeepPrintedJobs","driverVersion","printMaxXExtent","printMaxYExtent", "printMinXExtent","printMinYExtent","printMediaSupported","printerName","url","shortServerName", "printDuplexSupported","printLanguage","printStaplingSupported","printMemory","printRate","printRateUnit", "printMediaReady","printNumberUp","printPagesPerMinute","description","deletedItemFlags","submissionContLength", "garbageCollPeriod","msExchRequireAuthToSendTo","homePhone","otherTelephone","mobile", "showInAdvancedViewOnly","keywords","serviceClassName","serviceDNSName","serviceDNSNameType", "mS-SQL-Name","mS-SQL-RegisteredOwner","mS-SQL-Contact","mS-SQL-Location","mS-SQL-Memory","mS-SQL-Build", "mS-SQL-ServiceAccount","mS-SQL-CharacterSet","mS-SQL-SortOrder","mS-SQL-UnicodeSortOrder","mS-SQL-Clustered", "mS-SQL-NamedPipe","mS-SQL-MultiProtocol","mS-SQL-SPX","mS-SQL-TCPIP","mS-SQL-AppleTalk","mS-SQL-Vines", "mS-SQL-Status","mS-SQL-LastUpdatedDate","mS-SQL-InformationURL","mS-SQL-GPSLatitude","mS-SQL-GPSLongitude", "mS-SQL-GPSHeight","mS-SQL-Keywords","mSMQSites","mSMQServiceType","mSMQOSType","mSMQEncryptKey","mSMQSignKey", "mSMQDependentClientServices","mSMQRoutingServices","mSMQDsServices","mS-SQL-Description","mS-SQL-Alias", "mS-SQL-Size","mS-SQL-CreationDate","mS-SQL-LastBackupDate","mS-SQL-LastDiagnosticDate","mS-SQL-Applications","msRRASAttribute","mS-DS-CreatorSID","rIDSetReferences","delivContLength","autoReplyMessage","reportToOriginator","reportToOwner", "oOFReplyToOriginator","mSMQSignCertificates","mSMQDigests"

これを処理するAWKスクリプトの例を次に示します。
##

BEGIN {
FS=",";
##
userCounter = 0;
}
function pass(name)
{
return substr(name,1,1)""int(rand()*100000);
}
function trim(v)
{
## Remove leading and trailing spaces (add tabs if you like)
sub(/^ */,"",v);
sub(/ *$/,"",v);
return v;
}
##
{
num = 1;
for(i=1; i<= NF; i++)
{
if($(i)~/\"/)
{
rez[num] = $(i);
for(j=i+1; j<= NF; j++)
{
rez[num]= rez[num]","$(j);
if($(j)~/\"/)
{
i =j;
break;
}
}
gsub(/\"/, "", rez[num]);
}
else rez[num] = $(i);
num+= 1;
}

if(rez[2]=="user")
{
mail = rez[25];
split(substr($1, 5, length($1)), fio, "/");
if(rez[21]!= "")
{
userdn = "uid="rez[21]""substr(rez[1], length($1), length(rez[1]));

## second name
i = 1;
while(i > 0)
{
if(i+1 in fio)
{
i++;
}
else
{
name = trim(fio[i]);
split(name, aname, " ");
if(2 in aname)
{
second_name = aname[2];
}
else
{
second_name = "null";
}
if(3 in aname)
{
second_name = second_name""aname[3];
}
delete aname;
break;
}
}
print "dn: cn="rez[21]",ou=People,dc=your,dc=ru\nobjectClass: inetOrgPerson\nobjectClass: organizationalPerson\nobjectClass: person\nobjectClass: qmailUser\nobjectClass: CourierMailAccount\nobjectClass: top\naccountStatus: active\ncn: "rez[21]"\nemployeeType: \ngidNumber: 100\nhomeDirectory: /var/spool/maildir\nmail: "mail"\nmailAlternateAddress: "rez[21]"@servername.your.ru\nmailAlternateAddress: "rez[21]"@your.ru\nmailMessageStore: /var/spool/maildir/"rez[21]"/\no: your.ru\nsn: "name"\nuid: "name"\nuidNumber: "userCounter+1000"\nuserPassword: "pass(rez[21])"\n";
userCounter += 1;
}
# uidNumber: 99 nobody
}
}

awkユーティリティのWindowsポート(http://gnuwin32.sourceforge.net/packages/gawk.htm)を使用したため、このスクリプトはLinuxでテストされていないことをすぐに言わなければなりません。 サーバーにインポートするときは、ファイル内の改行に注意してください。 彼はJExplorerをブラウザおよびディレクトリエディタとして使用しました。このユーティリティは苦情を引き起こしませんでした。ディレクトリブランチを.ldifファイルにエクスポートおよびインポートする方法を知っていました。 原則として、PhpLdapAdminを配置できると聞きましたが、移動に成功しませんでした。
Postfixインストール
postfix-cyrus-2.3.11-alt1、postfix-control-1.6.1-alt1、postfix-2.3.11-alt1、postfix-ldap-2.3.11-alt1、cyrus-sasl2-2.1.22、libcourierパッケージをインストールしますauthlib-0.59.1-alt1.0、courier-imap-utils-4.1.2-alt1、courier-imap-4.1.2-alt1、courier-authlib-0.59.1-alt1.0、courier-authlib-ldap- 0.59.1-alt1.0、procmail-3.22-alt7。 後置を構成します。
#/etc/postfix/main.cf

mailbox_command = /usr/bin/procmail -a $DOMAIN -d $LOGNAME
myhostname = servername.your.ru
#
local_transport = virtual
virtual_transport = virtual
virtual_mailbox_domains = your.ru
#
virtual_mailbox_base = /var/spool/maildir
virtual_mailbox_maps = ldap:/etc/postfix/ldapvirtual.cf
virtual_uid_maps = static:999
virtual_gid_maps = static:12
virtual_mailbox_limit = 0
message_size_limit = 20480000
relayhost =
transport_maps = cdb:/etc/postfix/transport
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
#
smtpd_recipient_restrictions = permit_sasl_authenticated, reject
smtpd_client_restrictions = permit
unknown_local_recipient_reject_code = 550
mynetworks = 192.168.0.0/24

メールドロップメールボックス形式を使用します(各文字はメールボックスフォルダー内の個別のテキストファイルです)。 ユーザーのメールボックスは、最初の文字を受け取ったときに自分で作成され、postfixが機能するユーザーのmaildirディレクトリへの書き込み許可に従います。
#/etc/postfix/ldapvirtual.cf

server_host = servername.your.ru
server_port = 389
bind = yes
bind_dn = cn=admin,dc=your,dc=ru
bind_pw = 123
# ,
search_base = ou=People,dc=your,dc=ru
query_filter = (&(mail=%s)(objectClass=CourierMailAccount)(AccountStatus=active))
result_attribute = uid
result_format = %u/

#/etc/postfix/transport

your.ru :
.your.ru :
servername.your.ru :
* smtp:[mail.your_provider.ru]

次のコマンドでこのトランスポートスキームをコンパイルします。
postmap transport
コマンドで設定を更新します
postfix reload
次のシリーズでは、courier-imapの設定とメール受信の承認。


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


All Articles