
もくじ
この記事の概要
ちょっと特殊な構成です。
- メールサーバ、WEBサーバの2台構成
- メールサーバ側
 ・送信アカウント認証とSMTPtls465のみの管理を行うという特殊なSMTPサーバ
 ・アドレス管理はPostfixAdminは使わず、Laravelで自作する
- WEBサーバ側
 Pear::Mailを利用してメールサーバ経由でメール送信を行う
一般的なPostfix+Dovecot+MySQL+PostfixAdmin構成はこちらをどうぞ
仕様
- MySQLのクエリでPostfixのSASLアカウントをシンプルに追加出来る
- 465番SMTPSのみ待ち受け
- WEBサーバからメールをSASL認証後に中継して転送する
postfixバージョン
# postconf | grep mail_version mail_version = 2.10.1
MySQLのクエリでアカウント追加する
例:user1@example.netアドレスを利用出来るようにする
- ユーザ:user1@example.net
- パスワード:PasswordDayo
ドメイン追加
INSERT INTO `domain` (`domain`, `active`) VALUES
('example.net', 1)
ユーザ追加
INSERT INTO `mailbox` (`username`, `password`,`domain`, `active`) VALUES
('user1@example.net', 'PasswordDayo', 'example.net', 1);
他の仕様
- データベース:postfix
- メールサーバホスト:mail1.example.net
- 登録ドメイン1:example.net
 登録アドレス:tarou@example.net
- 登録ドメイン2:example.com
 登録アドレス:hanako@example.com
メールサーバ側
yum groupinstall -y "Development Tools" yum install -y yum-priorities yum install -y epel-release rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm yum install -y gcc httpd httpd-devel mod_ssl libcap-devel yum install -y --enablerepo=remi-php71,epel php php-cli php-devel php-common php-mbstring php-mysql php-phpunit-PHPUnit php-pecl-xdebug php-gd php-gmp php-pdo php-xml php-mcrypt php-fpm php-pear php-opcache php-imap yum install -y cyrus-sasl-*
cyrus-sasl-*のモジュールは重要で見落としやすい。
# vi /etc/php.ini [Date] ; Defines the default timezone used by the date functions ; http://php.net/date.timezone ;date.timezone = date.timezone = 'Asia/Tokyo'
ln -sf /usr/share/zoneinfo/Japan /etc/localtime
yum install -y http://repo.mysql.com/mysql-community-release-el7.rpm yum install -y mysql mysql-devel mysql-server mysql-utilities mysql-community-common
systemctl start mysqld systemctl enable mysqld
# cat /var/log/mysqld.log | grep root 2019-03-06T06:01:10.632243Z 5 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: atyGiql(o8jo
# mysql --version mysql Ver 8.0.15 for Linux on x86_64 (MySQL Community Server - GPL)
# vi /etc/my.cnf # For advice on how to change settings please see # http://dev.mysql.com/doc/refman/8.0/en/server-configuration-defaults.html [mysqld] # # Remove leading # and set to the amount of RAM for the most important data # cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%. # innodb_buffer_pool_size = 128M # # Remove the leading "# " to disable binary logging # Binary logging captures changes between backups and is enabled by # default. It's default setting is log_bin=binlog # disable_log_bin # # Remove leading # to set options mainly useful for reporting servers. # The server defaults are faster for transactions and fast SELECTs. # Adjust sizes as needed, experiment to find the optimal values. # join_buffer_size = 128M # sort_buffer_size = 2M # read_rnd_buffer_size = 2M # # Remove leading # to revert to previous value for default_authentication_plugin, # this will increase compatibility with older clients. For background, see: # https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_default_authentication_plugin # default-authentication-plugin=mysql_native_password datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock ※下記を追加 collation_server = utf8mb4_ja_0900_as_cs_ks default_authentication_plugin = mysql_native_password default-password-lifetime = 0 ※ ここまで log-error=/var/log/mysqld.log pid-file=/var/run/mysqld/mysqld.pid
systemctl restart mysqld systemctl enable mysqld systemctl status mysqld
root初期パスワード確認
# grep 'root' /var/log/mysqld.log 2019-03-11T02:29:49.163975Z 5 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: jpiRfFFe7_?6
rootログイン
# mysql -u root -p mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'rootPassword>'; mysql> DELETE FROM mysql.user WHERE User = ''; mysql> FLUSH PRIVILEGES; mysql> CREATE USER 'postfix'@'localhost' IDENTIFIED BY 'postfixPassword'; mysql> CREATE DATABASE postfix CHARACTER SET utf8; mysql> GRANT ALL ON postfix.* to postfix@localhost; mysql> EXIT;
# cp -p /etc/postfix/main.cf /etc/postfix/main.cf.org
vi /etc/postfix/main.cf
myhostname = mail1.example.net
mydomain = example.net
myorigin = $mydomain
inet_interfaces = all
# Enable IPv4, and IPv6 if supported
inet_protocols = all
#mydestination = $myhostname, localhost.$mydomain, localhost
#mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
#mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain,
#       mail.$mydomain, www.$mydomain, ftp.$mydomain
mydestination =
#mynetworks = 168.100.189.0/28, 127.0.0.0/8
#mynetworks = $config_directory/mynetworks
#mynetworks = hash:/etc/postfix/network_table
mynetworks = 172.31.0.0/16, 127.0.0.0/8
#home_mailbox = Mailbox
#home_mailbox = Maildir/
home_mailbox = Maildir/
#smtpd_banner = $myhostname ESMTP $mail_name
#smtpd_banner = $myhostname ESMTP $mail_name ($mail_version)
smtpd_banner = ESMTP unknown
最終行に追加
smtpd_sasl_auth_enable = yes
smtpd_sasl_local_domain = $mydomain
smtpd_recipient_restrictions =
      permit_mynetworks
      permit_sasl_authenticated
      reject_unauth_destination
 
broken_sasl_auth_clients=yes
 
smtpd_client_restrictions =
      # permit_mynetworks,
      # reject_rbl_client all.rbl.jp,
      # reject_rbl_client list.dsbl.org,
      # reject_rbl_client bl.spamcop.net,
      # reject_rbl_client relays.ordb.org,
      # reject_rbl_client sbl-xbl.spamhaus.org
 
### clamav
#smtpd_milters = unix:/var/run/clamav/clamav-milter.sock
#non_smtpd_milters = unix:/var/run/clamav/clamav-milter.sock
#milter_default_action = accept
 
### Postfix admin settings
local_transport = local
virtual_transport = virtual
virtual_mailbox_base = /home/mailuser
virtual_mailbox_domains = mysql:/etc/postfix/mysql_virtual_domains_maps.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf
virtual_minimum_uid = 5000
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000
###TLS
smtp_use_tls = yes
smtp_tls_security_level = may
smtp_tls_loglevel = 1
smtp_tls_received_header = yes
smtpd_tls_cert_file = /etc/pki/tls/certs/mail.pem
smtpd_tls_key_file = /etc/pki/tls/certs/mail.pem
smtpd_tls_session_cache_database = btree:/var/lib/postfix/smtpd_scache
smtpd_tls_session_cache_timeout = 3600s
# vi /etc/postfix/mysql_virtual_domains_maps.cf user = postfix password = postfixPassword hosts = localhost dbname = postfix query = SELECT domain FROM domain WHERE domain='%u'
vi /etc/postfix/mysql_virtual_mailbox_maps.cf user = postfix password = postfixPassword hosts = localhost dbname = postfix query = SELECT maildir FROM mailbox WHERE username = '%s' AND active = '1'
cp -p /etc/postfix/master.cf /etc/postfix/master.cf.org
465 SMTPSのみ許可する
# vi /etc/postfix/master.cf #smtp inet n - n - - smtpd #smtp inet n - n - 1 postscreen #smtpd pass - - n - - smtpd #dnsblog unix - - n - 0 dnsblog #tlsproxy unix - - n - 0 tlsproxy #submission inet n - n - - smtpd # -o syslog_name=postfix/submission # -o smtpd_tls_security_level=encrypt # -o smtpd_sasl_auth_enable=yes # -o smtpd_reject_unlisted_recipient=no # -o smtpd_client_restrictions=$mua_client_restrictions # -o smtpd_helo_restrictions=$mua_helo_restrictions # -o smtpd_sender_restrictions=$mua_sender_restrictions # -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject # -o milter_macro_daemon_name=ORIGINATING smtps inet n - n - - smtpd # -o syslog_name=postfix/smtps -o smtpd_tls_wrappermode=yes -o smtpd_sasl_auth_enable=yes -o smtpd_client_restrictions=permit_sasl_authenticated,reject # -o smtpd_reject_unlisted_recipient=no # -o smtpd_client_restrictions=$mua_client_restrictions # -o smtpd_helo_restrictions=$mua_helo_restrictions # -o smtpd_sender_restrictions=$mua_sender_restrictions -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject # -o milter_macro_daemon_name=ORIGINATING #628 inet n - n - - qmqpd pickup unix n - n 60 1 pickup cleanup unix n - n - 0 cleanup qmgr unix n - n 300 1 qmgr #qmgr unix n - n 300 1 oqmgr tlsmgr unix - - n 1000? 1 tlsmgr
# groupadd -g 5000 mailuser # useradd -u 5000 -g 5000 -d /home/mailuser -s /sbin/nologin mailuser
# cp -p /etc/sasl2/smtpd.conf /etc/sasl2/smtpd.conf.org
# vi /etc/sasl2/smtpd.conf #pwcheck_method: saslauthd #mech_list: plain login pwcheck_method: auxprop auxprop_plugin: sql allowplaintext: yes mech_list: plain login sql_engine: mysql sql_hostnames: localhost sql_user: postfix sql_passwd: postfixPassword sql_database: postfix sql_select: SELECT password FROM mailbox WHERE username = '%u@%r' AND active = '1'
# cd /etc/pki/tls/certs/
# make mail.pem umask 77 ; \ PEM1=`/bin/mktemp /tmp/openssl.XXXXXX` ; \ PEM2=`/bin/mktemp /tmp/openssl.XXXXXX` ; \ /usr/bin/openssl req -utf8 -newkey rsa:2048 -keyout $PEM1 -nodes -x509 -days 365 -out $PEM2 ; \ cat $PEM1 > mail.pem ; \ echo "" >> mail.pem ; \ cat $PEM2 >> mail.pem ; \ rm -f $PEM1 $PEM2 Generating a 2048 bit RSA private key ............+++ ...................................................................................+++ writing new private key to '/tmp/openssl.nZXB5D' ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [XX]:JP State or Province Name (full name) []:Tokyo Locality Name (eg, city) [Default City]: Organization Name (eg, company) [Default Company Ltd]: Organizational Unit Name (eg, section) []: Common Name (eg, your name or your server's hostname) []:mail1.example.net Email Address []:
# vi /etc/httpd/conf.d/mail1.example.net.conf
 
 
<VirtualHost *:443>
    ServerName mail1.example.net
    DocumentRoot /home/mailuser/public_html
    ErrorLog logs/virtual-error_log
    CustomLog logs/virtual-access_log combined env=!no_log
<Directory "/home/mailuser/public_html">
    AllowOverride all
</Directory>
    SSLEngine on
    SSLCertificateFile /etc/pki/tls/certs/localhost.crt
    SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
</VirtualHost>
# mkdir /home/mailuser/public_html
# vi /home/mailuser/public_html/index.php <?php echo "http://mail1.example.net/";
chmod 711 /home/mailuser chmod 711 /home/mailuser/public_html
systemctl restart httpd systemctl enable httpd
yum install wget cd /usr/local/src/ wget https://files.phpmyadmin.net/phpMyAdmin/4.6.4/phpMyAdmin-4.6.4-all-languages.zip unzip phpMyAdmin-4.6.4-all-languages.zip rm -rf phpMyAdmin-4.6.4-all-languages.zip mv phpMyAdmin-4.6.4-all-languages /home/mailuser/public_html/xxxphpMyAdmin
mysql> use postfix;
CREATE TABLE `domain` (
  `id` int auto_increment,
  `domain` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL,
  `active` tinyint(1) NOT NULL DEFAULT '1',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `domain` (`domain`, `active`) VALUES
('ALL', 1),
('example.net', 1),
('example.com', 1);
CREATE TABLE `mailbox` (
  `username` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL,
  `password` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL,
  `domain` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL,
  `active` tinyint(1) NOT NULL DEFAULT '1',
  `created_at` timestamp,
  `updated_at` timestamp,
  PRIMARY KEY (`username`),
  KEY `domain` (`domain`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `mailbox` (`username`, `password`, `domain`, `active`) VALUES
('tarou@example.net', 'passwordDeath', 'example.net', 1),
('hanako@example.com', 'passwordDeath', 'example.com', 1);
systemctl restart postfix systemctl enable postfix systemctl status postfix systemctl restart saslauthd systemctl enable saslauthd systemctl status saslauthd
WEBサーバ側
# yum install httpd postfix mail php php-* # systemctl enable httpd # systemctl restart httpd
# vi /etc/php.ini [Date] ; Defines the default timezone used by the date functions ; http://php.net/date.timezone ;date.timezone = date.timezone = 'Asia/Tokyo'
ln -sf /usr/share/zoneinfo/Japan /etc/localtime
# pear channel-update pear.php.net Updating channel "pear.php.net" Update of Channel "pear.php.net" succeeded
# pear install -a Mail WARNING: "pear/Auth_SASL" is deprecated in favor of "pear/Auth_SASL2" downloading Mail-1.4.1.tgz ... Starting to download Mail-1.4.1.tgz (21,756 bytes) ........done: 21,756 bytes downloading Net_SMTP-1.8.1.tgz ... Starting to download Net_SMTP-1.8.1.tgz (14,931 bytes) ...done: 14,931 bytes downloading Net_Socket-1.2.2.tgz ... Starting to download Net_Socket-1.2.2.tgz (6,903 bytes) ...done: 6,903 bytes downloading Auth_SASL-1.1.0.tgz ... Starting to download Auth_SASL-1.1.0.tgz (9,380 bytes) ...done: 9,380 bytes install ok: channel://pear.php.net/Mail-1.4.1 install ok: channel://pear.php.net/Net_Socket-1.2.2 install ok: channel://pear.php.net/Auth_SASL-1.1.0 install ok: channel://pear.php.net/Net_SMTP-1.8.1
# vi /var/www/html/mailsend.php
<?php
require_once("/usr/share/pear/Mail.php");
mb_language("japanese");
mb_internal_encoding("UTF-8");
$params = array(
        'host'     => 'tls://mail1.example.net',
        'port'     => 465,
        'auth'     => true,
        'username' => 'tarou@example.net',
        'password' => 'passwordDeath',
        'debug'    => false,
        'protocol'=>'SMTP_AUTH'
);
$headers = array(
  'From'    => 'tarou@example.net',
  'To'      => 'target@hoge.com',
  'Subject' => mb_encode_mimeheader(mb_convert_encoding("TEST1643","JIS","UTF-8")),
  'Date'    => date('r')
);
$recipients = 'target@hoge.com';
$body = mb_convert_encoding("メールの内容","JIS","UTF-8");
$smtp = Mail::factory('smtp', $params);
$e = $smtp->send($recipients, $headers, $body);
if ( PEAR::isError($e) ) echo $e->getMessage() . "\n";
メールが届くことを確認出来た
メールサーバ側
メールアドレス管理アプリ作成
Laravelフレームワークでざっくり作っていきます。
WEBユーザの作成
sudo useradd mailKanri sudo usermod -aG apache mailKanri sudo usermod -aG wheel mailKanri
# visudo ## Same thing without a password %wheel ALL=(ALL) NOPASSWD: ALL
# vi /etc/httpd/conf/httpd.conf #User apache User MailKanri Group apache
httpd -t systemctl restart httpd systemctl enable httpd
Composerインストール
curl -sS https://getcomposer.org/installer | php sudo mv composer.phar /usr/local/bin/composer
# mkdir -p /var/www/vhosts/mail1.yuulinux.tokyo/ # composer global require laravel/installer # composer create-project laravel/laravel /var/www/vhosts/mail1.yuulinux.tokyo/project --prefer-dist
chmod 755 /var/www/vhosts/mail1.yuulinux.tokyo/project chmod 755 -R /var/www/vhosts/mail1.yuulinux.tokyo/project/storage chmod 755 -R /var/www/vhosts/mail1.yuulinux.tokyo/project/bootstrap/cache chown mailKanri:apache -R /var/www/vhosts/
ここからはWEBユーザで作業
$ su - mailKanri
DB接続設定
$ vi /var/www/vhosts/mail1.yuulinux.tokyo/project/.env DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=homestead DB_USERNAME=homestead DB_PASSWORD=secret ↓変更 DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=postfix DB_USERNAME=postfix DB_PASSWORD=<Postfixパスワード>
プロジェクトに移動
$ cd /var/www/vhosts/mail1.yuulinux.tokyo/project/
$ vi ./composer.json
 
(略)
 
    "require": {
        "php": "^7.1.3",
        "fideloper/proxy": "^4.0",
        "laravel/framework": "5.8.*",
        "laravel/tinker": "^1.0",
        "laravelcollective/html": "~5.0" ←追加
    },
 
(略)
$ composer update
認証make:auth
$ php artisan make:auth $ php artisan migrate
migrations, password_resets, usersテーブルが作成される
$ vi ./resources/views/layouts/layout.blade.php
<!DOCTYPE HTML>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>@yield('title')</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet" media="screen"
>
    <link href="/css/sticky-footer.css" rel="stylesheet" media="screen">
    <!-- Scripts -->
    <script src="{{ asset('js/app.js') }}" defer></script>
</head>
<body>
<!-- ヘッダー -->
@include('layouts.partials.header')
<div class="container">
  <div class="row" id="content">
  <div class="col-md-9">
  <!-- コンテンツ -->
  @yield('content')
  </div>
  </div>
</div>
$ mkdir ./resources/views/layouts/partials
$ vi ./resources/views/layouts/partials/header.blade.php <!-- header & grobal navi --> <nav class="navbar navbar-default" style="background-color: #FFFFFF;"> <div class="container-fluid"> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbarEexample2"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="/mailbox"> <strong>メール管理</strong> </a> </div> <div class="collapse navbar-collapse" id="navbarEexample2"> <ul class="nav navbar-nav"> <li class="active"><a href="/mailbox/">メニュー</a></li> <li><a href="/mailbox/add">新規登録</a></li> </ul> </div> </div> </nav>
$ vi ./resources/views/layouts/partials/footer.blade.php <!-- footer --> <footer class="footer"> <div class="container"> <p class="text-muted">Copyright (C) メールアドレス管理システム運営委員会 All Rights Reserved.</p> </div> </footer>
Mailboxリクエストの作成
$ php artisan make:request MailboxRequest
メールアドレス追加時のバリデーションルール
$ vi ./app/Http/Requests/MailboxRequest.php
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class MailboxRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        //return false;
        return true;
    }
    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'email'              => 'required|email|unique:mailbox,username',
            'password'           => 'required',
        ];
    }
    public function messages()
    {
        return [
            'email.required'        => 'メールアドレスを必ず入力して下さい。',
            'email.email'           => 'メールアドレスを確認して入力して下さい。',
            'email.unique'          => '既にメールアドレスは存在しています。',
            'password.required'     => 'パスワードは必ず入力して下さい。',
        ];
    }
}
Mailboxモデルの作成
$ mkdir ./app/Models $ php artisan make:model Models/Mailbox
$ vi ./app/Models/Mailbox.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
use Illuminate\Http\Request;
class Mailbox extends Model
{
    protected $table      = 'mailbox';             // テーブル名
    protected $primaryKey = 'username';            // PK
    protected $guarded    = array('username');     // PK
    public function getList(){
        $items = DB::table('mailbox')
                     ->select('mailbox.username', 'mailbox.password', 'mailbox.domain', 'mailbox.active')
                     ->orderBy('mailbox.created_at', 'DESC')
                     ->paginate(3);
        return $items;
    }
    public function add($request){
         $email = $request->email;
         $emailArray = explode('@', $email);
         $name   = $emailArray[0];
         $domain = $emailArray[1];
         $param_domain = [
            "domain"      => $domain,
            "active"      => $request->active,
        ];
        $param_mailbox = [
            "username"    => $email,
            "password"    => $request->password,
            "domain"      => $domain,
            "active"      => $request->active,
            'created_at'  => now(),
            'updated_at'  => now(),
        ];
        //DBに保存
        DB::insert('INSERT INTO domain (domain, active)
                                VALUES(:domain, :active)', $param_domain);
        DB::insert('INSERT INTO mailbox (username, password, domain, active, created_at, updated_at)
                                VALUES(:username, :password, :domain, :active, :created_at, :updated_at)', $param_mailbox);
    }
    public function show($request){
        $username = $request->username;
        $item = DB::table('mailbox')->where('mailbox.username', $username)
                     ->select('mailbox.username', 'mailbox.password', 'mailbox.domain', 'mailbox.active')
                     ->get()->first();
        return $item;
    }
    public function edit($request){
        $username_id = $request->username_id;
            $param = [
                "username"        => $request->username,
                "password"        => $request->password,
                "active"          => $request->active,
                'updated_at'      => now(),
            ];
            DB::table('mailbox')->where('username', $username_id)->update($param);
    }
}
Mailboxコントローラの作成
$ php artisan make:controller MailboxController
$ vi ./app/Http/Controllers/MailboxController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Mailbox;
use App\Http\Requests\MailboxRequest;
class MailboxController extends Controller
{
    public function index(){
        $mailbox = new Mailbox();
        $items = $mailbox->getList();
        return view('mailbox.index', ['items' => $items]);
    }
    public function mailbox_add(){
        return view('mailbox.add');
    }
    public function create(MailboxRequest $request){
        $mailbox = new Mailbox();
        $mailbox->add($request);
        return redirect('/mailbox/');
    }
    public function mailbox_edit(Request $request){
        $mailbox = new Mailbox();
        $item = $mailbox->show($request);
        return view('mailbox.edit', ['item' => $item]);
    }
    public function edit(Request $request){
        $mailbox = new Mailbox();
        $authFlg = $mailbox->edit($request);
        return redirect('/mailbox');
    }
    public function mailbox_act(){
        return view('mailbox.act');
    }
}
ビューの作成
$ mkdir ./resources/views/mailbox/
index
$ vi ./resources/views/mailbox/index.blade.php
 
@extends('layouts.layout')
@section('title', 'メールアドレス一覧')
@section('content')
 <div class="page-header" style="margin-top:-30px;padding-bottom:0px;">
  <h1><small>メールアドレスリスト</small></h1>
 </div>
<style>
td, th {
padding: 5px 10px;
}
</style>
 <table id="rowspan" cellspacing="0" class="tablesorter" border="1" >
        <thead>
                <tr>
                        <th width="20%">ユーザ名(メールアドレス)</th>
                        <th width="20%">パスワード</th>
                        <th width="22%">アクティブ</th>
                        <th width="20%">操作</th>
                </tr>
        </thead>
 @foreach($items as $item)
                <tbody>
                <tr><td>{{$item->username}}</td><td>{{$item->password}}</td><td>{{$item->active}}</td><td><a href="/mailbox/edit?username={{$item->username}}">編集</a></td></tr>
                </tbody>
 @endforeach
 </table>
 {{ $items->links() }}
@endsection
メールアドレスの追加
$ vi ./resources/views/mailbox/add.blade.php
@extends('layouts.layout')
@section('title', 'メールアドレス一覧')
@section('content')
 <div class="page-header" style="margin-top:-30px;padding-bottom:0px;">
  <h1><small>メールアドレスリスト</small></h1>
 </div>
<style>
.error {
    color: red;
}
</style>
@if(count($errors) > 0)
<span class="error" ><p>入力に問題があります。再入力して下さい。</p></span>
@endif
 <table class="table table-striped table-hover">
  {{Form::open(['action' => 'MailboxController@create', 'files' => false])}}
  <tr><th>メールアドレス</th><td><input type="text" name="email"></td></tr>
  @if($errors->has('email'))
  <tr><th><span class="error" >エラー!</span></th><td><span class="error" >{{ $errors->first('email') }}</span></td></tr>
  @endif
  <tr><th>パスワード</th><td><input type="text" name="password"></td><td></td></tr>
  @if($errors->has('password'))
  <tr><th><span class="error" >エラー!</span></th><td><span class="error" >{{ $errors->first('password') }}</span></td></tr>
  @endif
  <tr><th></th><td><input type="submit" value="追加"></td><td></td></tr>
  <input type="hidden" name="active" value="1">
  {{Form::close()}}
 </table>
@endsection
メールアドレス編集ページ
$ vi ./resources/views/mailbox/edit.blade.php
@extends('layouts.layout')
@section('title', 'メールアドレス一覧')
@section('content')
 <div class="page-header" style="margin-top:-30px;padding-bottom:0px;">
  <h1><small>メールアドレスリスト</small></h1>
 </div>
<style>
td, th {
padding: 5px 10px;
}
</style>
 <table id="rowspan" cellspacing="0" class="tablesorter" border="1" >
 {{Form::open(['action' => 'MailboxController@edit', 'files' => false])}}
        {{ csrf_field() }}
        <input type="hidden" name=username_id value="{{$item->username}}">
        <thead>
                <tr>
                        <th width="20%">ユーザネーム(メールアドレス)</th>
                        <th width="20%">パスワード</th>
                        <th width="22%">アクティブ</th>
                        <th width="20%">操作</th>
                </tr>
        </thead>
                <tbody>
                 <tr>
                     <td><input type="text" name="username" value="{{$item->username}}"></td>
                     <td><input type="text" name="password" value="{{$item->password}}"></td>
                     <td><select name="active">
                          <option value="{{$item->active}}" selected>{{$item->active}}</option>
                          @if($item->active == 0)
                          <option value="1">1</option>
                          @endif
                          @if($item->active == 1)
                          <option value="0">0</option>
                          @endif
                         </select>
                     </td>
                     <td>{{ Form::submit('編集実行', ['class' => 'btn']) }}</td>
                 </tr>
                </tbody>
 </table>
@endsection
ルーティング
$ vi /var/www/vhosts/mail1.yuulinux.tokyo/project/routes/web.php
<?php
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
    return view('welcome');
});
Auth::routes();
//Route::get('/', 'HomeController@index')->name('home');
Route::get('/',              'MailboxController@index')->middleware('auth');
Route::get('/mailbox',       'MailboxController@index')->middleware('auth');
Route::get('/mailbox/add',   'MailboxController@mailbox_add')->middleware('auth');
Route::post('/mailbox/add',  'MailboxController@create')->middleware('auth');
Route::get('/mailbox/edit',  'MailboxController@mailbox_edit')->middleware('auth');
Route::post('/mailbox/edit',  'MailboxController@edit')->middleware('auth');
ログイン後のリダイレクト先変更
$ vi ./app/Http/Middleware/RedirectIfAuthenticated.php
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class RedirectIfAuthenticated
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @param  string|null  $guard
     * @return mixed
     */
    public function handle($request, Closure $next, $guard = null)
    {
        if (Auth::guard($guard)->check()) {
            //return redirect('/home');
            return redirect('/mailbox');
        }
        return $next($request);
    }
}
アカウントの作成
https://IPアドレス/register
レジスターにアクセスしてアカウントを作成して下さいね~!
ログイン

https://IPアドレス/login

ログイン出来た

編集ページ
アクティブ1でSMTPアカウントは有効、0にするとそのアカウントではSMTP認証出来なくなる仕様です。
ログイン出来たらレジスターの無効化
$ vi ./app/Http/Controllers/Auth
    public function __construct()
    {
        $this->middleware('guest');
    }
    
↓変更
    public function __construct()
    {
        //$this->middleware('guest');
        abort(404);
    }
メールサーバ側のWEBにはIP制限をかけるなどしたほうが良いでしょう。


