メール, Linux

PostfixSMTP+MySQL+Laravel+CentOS

この記事の概要

ちょっと特殊な構成です。

  • メールサーバ、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制限をかけるなどしたほうが良いでしょう。

 

 

Amazonおすすめ

iPad 9世代 2021年最新作

iPad 9世代出たから買い替え。安いぞ!🐱 初めてならiPad。Kindleを外で見るならiPad mini。ほとんどの人には通常のiPadをおすすめします><

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)