Postfix - amavisd-new tanpa localhost atau server mail dengan cara baru

Ada banyak instruksi tentang cara menaikkan server mail pada sekelompok postfix - amavisd-new - dovecot. Dan sebagian besar dari mereka saling mengulang hampir setiap kata, termasuk kesalahan dan ketidakakuratan.

Tampaknya membosankan bagi saya untuk menekan tombol tanpa berpikir, jadi saya memutuskan untuk mengoptimalkan konfigurasi standar: bagaimana jika saya membangun interaksi postfix dan amavisd-baru bukan melalui localhost, tetapi pada soket unix?

Ternyata, semuanya tidak begitu sederhana, tetapi saya berhasil! Instruksi dan tambalan di bawah luka.

Jujur, saya biasanya tidak suka interaksi melalui localhost di mesin yang sama. Jika Anda ingin mengatur pertukaran data antara dua aplikasi, maka jauh lebih tepat, lebih aman dan kurang sumber daya intensif untuk melakukan ini melalui soket unix pada sistem file. Selain itu, dengan cara ini Anda dapat mengatur perlindungan (melalui hak atas sistem file) bahkan ketika tidak ada pada tingkat aplikasi atau protokol.

Jadi, jalur surat dalam kelompok yang dibahas terlihat seperti ini:



Ternyata kita perlu mengatur dua koneksi: ketika mentransfer ke pemfilteran dan ketika kembali ke MTA. Karena soket dibuat oleh pendengar, pada kasus pertama akan dibuat, dan pada postfix kedua.

Mari kita mulai dengan yang kedua, karena lebih sederhana dan lebih baik dijelaskan. Agar postfix membuat soket pendengaran, Anda hanya perlu menentukan unix, bukan inet, di kolom kedua master.cf (kolom tipe). Dalam hal ini, kolom pertama menentukan path dan nama file dari socket.

Karena proses postfix bekerja dalam chroot (ini dapat dinonaktifkan untuk proses tertentu, tetapi tidak sepadan), Anda perlu membuat folder di dalam direktori home postfix: / var / spool / postfix. Ini akan memiliki kedua soket:

mkdir /var/spool/postfix/amavis chown amavis:postfix /var/spool/postfix/amavis chmod 770 /var/spool/postfix/amavis 

Konfigurasi well dan postfix:

 amavis/postfix-in unix y - y - - smtpd -o smtpd_client_restrictions=$local_clients_only -o smtpd_helo_restrictions= -o smtpd_sender_restrictions= -o smtpd_recipient_restrictions= -o smtpd_milters= 

Opsi spesifik tergantung pada pengaturan Anda, ini adalah opsi saya.

Ada dua masalah:

  1. Path akan relatif ke / var / spool / postfix / private, yang tunduk pada izin yang sangat ketat.
  2. Tidak yakin apakah ini benar di semua distribusi, tetapi di Ubuntu pasti. Lebih baik tidak menyentuh hak ke folder (soket semua layanan postfix ada di sana), lebih baik buat saja symlink.
  3. Selain soket, postfix juga membuat file pid untuk proses, nama yang secara otomatis dihasilkan oleh mask dari $ type. $ Name. Di mana tipe akan sama dengan unix, dan nama diambil dari kolom pertama master.cf. Ternyata unux.amavis / postfix-in i.e. file dalam subfolder. Dia sendiri tidak akan membuatnya dan akan jatuh dengan kesalahan.

Jadi, kami mengganti kruk:

 cd /var/spool/postfix/private ln -s ../amavis . mkdir /var/spool/postfix/pid/unix.amavis 

Tidak terlalu bagus, tetapi tidak merusak untuk struktur folder reguler paket.

Kami me-restart postfix dan memastikan bahwa file socket muncul di folder amavis dan file pid di pid / unix.amavis. Sayangnya, hak atas soket adalah 666, tetapi hak atas folder yang Anda buat sebelumnya akan melindungi file dari mata yang tidak perlu.

Anda dapat memeriksa pekerjaan dengan perintah:

 netcat -U /var/spool/postfix/amavis/postfix-in 220 mail.example.ru ESMTP Postfix 

Yah, mereka berhasil. Sekarang untuk memukau.

Pertama, konfigurasikan jalur pengembalian surat melalui soket unix yang dimiliki oleh postfix. Ini bekerja di luar kotak:

 $forward_method = 'smtp:/var/spool/postfix/amavis/postfix-in'; $notify_method = \$forward_method; 

Nah, sekarang bagian tersulit adalah menyiapkan soket di amavisd. Solusinya dapat ditemukan di Internet , tetapi ada yang mengusulkan untuk menggunakan soket tunggal yang ditentukan oleh parameter $ unix_socketname. Saya juga menginginkan protokol amavisd-new (AM.PDP) dan penerimaan email melalui soket.

File konfigurasi default berisi referensi ke direktif @listen_sockets, tetapi tidak ada deskripsi untuk itu. Tetapi ada dalam catatan rilis , bahkan dengan contoh! Benar, hanya ada satu soket, tetapi apa yang mencegah Anda mencoba?

OK, tapi bagaimana cara mengatur protokol untuk soket (yang ditentukan di bank kebijakan)? Dalam semua contoh, mereka hanya menulis SOCK. Dengan analogi dengan soket inet (Anda dapat menentukan port host di sana), saya menyarankan Anda untuk menentukan path lengkap ke file socket. Inilah yang terjadi:

 $unix_socketname = undef; $inet_socket_bind = undef; $inet_socket_port = undef; @listen_sockets = ('/var/lib/amavis/amavisd.sock', '/var/spool/postfix/amavis/amavis-in.sock'); $unix_socket_mode = 0660; %interface_policy = ( '/var/lib/amavis/amavisd.sock' => 'AM.PDP-SOCK', '/var/spool/postfix/amavis/amavis-in.sock' => 'LMTP-SOCK' ); $policy_bank{'LMTP-SOCK'} = { protocol => 'LMTP' }; $policy_bank{'AM.PDP-SOCK'} = { protocol => 'AM.PDP', auth_required_release => 0, # don't require secret-id for release }; 

Mulai ulang, periksa - memang, kedua soket telah dibuat! Kemenangan Tidak juga, ketika Anda mencoba menyambungkan ke soket, tidak ada yang terjadi, dan kesalahan ditulis ke log bahwa protokol tidak ditentukan untuk itu. Ternyata bank kebijakan tidak berlaku untuk mereka.

Bagaimana bisa begitu? Saya harus pergi ke kode.

Kampanye ini membawa dua berita - seperti biasa, baik dan buruk. Yang bagus adalah asumsi tentang% interface_policy benar:

 # load policy banks according to my socket (destination), # then check for allowed access from the peer (client/source) # sub access_is_allowed($;$$$$) { my($unix_socket_path, $src_addr, $src_port, $dst_addr, $dst_port) = @_; my(@bank_names); if (defined $unix_socket_path) { push(@bank_names, $interface_policy{"SOCK"}); push(@bank_names, $interface_policy{$unix_socket_path}); } elsif (defined $dst_addr && defined $dst_port) { $dst_addr = '['.lc($dst_addr).']' if $dst_addr =~ /:[0-9a-f]*:/i; # IPv6? push(@bank_names, $interface_policy{$dst_port}); push(@bank_names, $interface_policy{"$dst_addr:$dst_port"}); } load_policy_bank($_) for @bank_names; 

Yang buruk adalah $ unix_socket_path datang ke fungsi ini kosong. Diisi sebagai berikut:

 my $is_ux = $sock && $sock->UNIVERSAL::can('NS_proto') && $sock->NS_proto eq 'UNIX'; 

Dan kedua properti kosong di sana.

Sebuah studi dokumentasi menyarankan opsi ini:

 my $unix_socket_path = $sock->hostpath(); 

Dan itu berhasil! Ready .patch bisa dikatakan di sini .

Ada sentuhan terakhir. Karena amavisd membuat soket sendiri dengan hak hanya untuk dirinya sendiri, dan kami telah menolak akses ke yang lain (yang benar), kami perlu menambahkan postfix ke grup amavis sehingga dapat menulis ke soket:

 gpasswd -a postfix amavis 

Selesai

PS: Saya mengirim tambalan dan deskripsi masalah oleh Mark Martinec melalui surat karena saya tidak menemukan penyebut bug di situs . Saya masih belum menerima jawaban, tetapi saya tidak benar-benar mengandalkannya - proyek ini terlihat ditinggalkan (rilis terakhir lebih dari dua tahun yang lalu).

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


All Articles