搜尋此網誌

顯示具有 Linux 標籤的文章。 顯示所有文章
顯示具有 Linux 標籤的文章。 顯示所有文章

2015年9月4日 星期五

CentOS7 安裝Opentack - Keystone

環境準備

目前Openstack最新版本為KILO,先安裝KILO的Repository:


安裝Mariadb :
[root@keystone ~]# yum install mariadb mariadb-server MySQL-python -y


修改my.cnf :
[root@keystone ~]# vim /etc/my.cnf
[mysqld]
...
# near line 10 add
default-storage-engine = innodb
innodb_file_per_table
collation-server = utf8_general_ci
init-connect = 'SET NAMES utf8'
character-set-server = utf8


啟動MariaDB並初始化設定:
[root@keystone ~]# systemctl enable mariadb.service
[root@keystone ~]# systemctl start mariadb.service
[root@keystone ~]# mysql_secure_installation


建立keystone資料庫,並新增一個keystone的使用者 :
[root@keystone ~]# mysql -u root -p 
MariaDB [(none)]> CREATE DATABASE keystone;
MariaDB [(none)]> GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'localhost' IDENTIFIED BY 'YOURPASSWORD';
MariaDB [(none)]> GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'%' IDENTIFIED BY 'YOURPASSWORD';


安裝Keystone


安裝套件 :
[root@keystone ~]# yum install openstack-keystone httpd mod_wsgi python-openstackclient memcached python-memcached  -y


新版的安裝建議使用apache的wsgi模組啟動keystone,因此安裝httpd與mod_wsgi這兩個套件。



設定keystone.conf :
[root@keystone ~]# vim /etc/keystone/keystone.conf

#line 12 uncomment 
admin_token = YOURTOKEN

# line 419 uncomment
connection = mysql://keystone:YOURPASSWORD@localhost/keystone

# line 1126 uncomment
servers = localhost:11211

# line 1496 uncomment
driver = keystone.contrib.revoke.backends.sql.Revoke

# line 1685 uncomment
provider = keystone.token.providers.uuid.Provider

# line 1688 uncomment
driver = keystone.token.persistence.backends.memcache.Token


啟動memcached :
[root@keystone ~]# systemctl enable memcached.service 
[root@keystone ~]# systemctl start memcached.service 


初始化Keystone 資料庫 :
[root@keystone ~]# su -s /bin/sh -c "keystone-manage db_sync" keystone 



設定apache mod_wsgi


新增一個wsgi的apache設定檔 :
[root@keystone ~]# vim  /etc/httpd/conf.d/wsgi-keystone.conf

# add following
Listen 5000
Listen 35357
<VirtualHost *:5000>
 WSGIDaemonProcess keystone-public processes=5 threads=1 user=keystone group=keystone display-name=%{GROUP}
 WSGIProcessGroup keystone-public
 WSGIScriptAlias / /var/www/cgi-bin/keystone/main
 WSGIApplicationGroup %{GLOBAL}
 WSGIPassAuthorization On
 LogLevel info
 ErrorLogFormat "%{cu}t %M"
 ErrorLog /var/log/httpd/keystone-error.log
 CustomLog /var/log/httpd/keystone-access.log combined
</VirtualHost>
<VirtualHost *:35357>
 WSGIDaemonProcess keystone-admin processes=5 threads=1 user=keystone group=keystone display-name=%{GROUP}
 WSGIProcessGroup keystone-admin
 WSGIScriptAlias / /var/www/cgi-bin/keystone/admin
 WSGIApplicationGroup %{GLOBAL}
 WSGIPassAuthorization On
 LogLevel info
 ErrorLogFormat "%{cu}t %M"
 ErrorLog /var/log/httpd/keystone-error.log
 CustomLog /var/log/httpd/keystone-access.log combined

</VirtualHost>


建立執行的資料夾,並下載執行檔 :
[root@keystone ~]# mkdir -p /var/www/cgi-bin/keystone
[root@keystone ~]# curl http://git.openstack.org/cgit/openstack/keystone/plain/httpd/keystone.py?h=stable/kilo | tee /var/www/cgi-bin/keystone/main /var/www/cgi-bin/keystone/admin


修改權限並啟動apache :
[root@keystone ~]# chown -R keystone:keystone /var/www/cgi-bin/keystone
[root@keystone ~]# chmod 755 /var/www/cgi-bin/keystone/*

[root@keystone ~]# systemctl enable httpd.service
[root@keystone ~]# systemctl start httpd.service


到目前為止我們已經將Keystone的服務設定完畢,接下來我們將新增一個admin的使用者。


新增admin使用者


載入keystone的管理token :

[root@keystone ~]# vim ~/.keystone-admin-token
# add following
export OS_TOKEN=YOURTOKEN
export =http://localhost:35357/v2.0

[root@keystone ~]# source ~/.keystone-admin-token



建立一個keystone的service :
[root@keystone ~]# openstack service create --name keystone --description "OpenStack Identity" identity


建立Endpoint ,若前端有Load balance的伺服器,則改成Load balance伺服器的IP或DNS名稱:
[root@keystone ~]# openstack endpoint create \
--publicurl http://192.168.10.221:5000/v2.0 \
--internalurl http://192.168.10.221:5000/v2.0 \
--adminurl http://192.168.10.221:35357/v2.0 \
--region RegionOne \
identity


建立一個admin的project與user,並設定密碼:
[root@keystone ~]# openstack project create --description "Admin Project" admin
[root@keystone ~]# openstack user create --password-prompt admin
User Password: YOURADMINPASSWORD
Repeat User Password: YOURADMINPASSWORD


建立一個admin的role,並將admin user加到此role :
[root@keystone ~]# openstack role create admin
[root@keystone ~]# openstack role add --project admin --user admin admin


新增admin的user後,要先將之前載入的keystone環境變數清掉,才能進行後面的測試 :
[root@keystone ~]# unset OS_TOKEN
[root@keystone ~]# unset OS_URL


測試


新增並載入admin user登入的環境變數檔 :
[root@keystone ~]# vim ~/.keystone-admin

# add following
export OS_PROJECT_DOMAIN_ID=default
export OS_USER_DOMAIN_ID=default
export OS_PROJECT_NAME=admin
export OS_TENANT_NAME=admin
export OS_USERNAME=admin
export OS_PASSWORD=YOURADMINPASSWORD
export OS_AUTH_URL=http://localhost:35357/v3

[root@keystone ~]# source ~/.keystone-admin


查看user屬於哪一個Project與Role :
[root@keystone ~]# openstack user role list
+------------------------------------------------+--------+----------+---------+
| ID                                                          | Name | Project | User   |
+------------------------------------------------+--------+----------+---------+
| c3704f46fa2846e99a8060f4a451d177 | admin | admin  | admin |
+------------------------------------------------+--------+----------+---------+




















2015年9月3日 星期四

CentOS7 - MariaDB 10 資料庫加密


MariaDB 從 10.1.3版開始支援table encryption,官方建議使用mariadb 10.1.4以上版本。

MariaDB Encryption 以table為最小的加密單位,據官方文件說啟用加密效能約下降10%,目前支援的 storage engine有InnoDB、XtraDB 和Aria。

雖然說它是加密的,但原理似乎跟Linux的LUKS硬碟加密差不多,在啟動MariaDB的時候需要有加密的Key檔,沒有Key檔就不能啟動,跟LUKS一樣都是在防止硬碟遭竊取時被打開來看,這樣說起來不是用硬碟加密就好了?(誤


環境準備

首先要先準備MariaDB官方的Yum Repository File :


目前(20150903)官方預設是使用Mariadb 10.0版,因此我們要將baseurl修改一下:

[root@jyc-blog ~]# cat /etc/yum.repos.d/mariadb.repo
[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.1/centos7-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1

安裝

用Yum安裝:
[root@jyc-blog ~]# yum install MariaDB-server MariaDB-client

啟動

跟Mariadb 5版不同,10版的服務名稱為mysql,且要用chkconfig設定開機啟動:
[root@jyc-blog ~]# systemctl start mysql.service
[root@jyc-blog ~]# chkconfig mysql on

接下來做一些簡單的設定:
[root@jyc-blog ~]# mysql_secure_installation

產生Key檔

首先用openssl這個指令產生:
[root@jyc-blog ~]# openssl enc -aes-256-cbc -k YOURPASSWORD -P -md sha1
salt=A1A4F8EF1CC6D09E
key=5D56081334F9252ABD4D641AC640907317604A8B3CA92BC94FD6769C0F746628
iv =F39393DD5C735D2B0614356C413569D4

Key檔的格式為: <key-id>;<iv>;<key> 

預設MariaDB會找編號為"1"的Key,因此我們將這把Key的id指定為"1",並將Key檔儲存在/etc/my.cnf.d :
[root@jyc-blog ~]# cd /etc/my.cnf.d/
[root@jyc-blog my.cnf.d]# vim keys.txt

#add following
1;F39393DD5C735D2B0614356C413569D4;5D56081334F9252ABD4D641AC640907317604A8B3CA92BC94FD6769C0F746628


再來將keys.txt加密,後面MariaDB讀取的就是加密後的Key檔:
[root@jyc-blog my.cnf.d]# openssl enc -aes-256-cbc -md sha1 -k YOURPASSWORD -in keys.txt -out keys.enc


MariaDB支援兩種加密演算法: AES_CBC和AES_CTR,官方建議使用AES_CTR,但需要較新的openssl版本 。


修改mariadb設定檔

編輯/etc/my.cnf.d/server.conf :
[root@jyc-blog my.cnf.d]# vim server.conf

# line 12 add following
default-storage-engine = innodb

plugin_dir=/usr/lib64/mysql/plugin
plugin-load-add=file_key_management.so

file-key-management
file_key_management_encryption_algorithm=aes_cbc
file_key_management_filename = /etc/my.cnf.d/keys.enc
file_key_management_filekey = YOURPASSWORD 
innodb-encrypt-log=ON
innodb-encryption-threads=4
innodb-encrypt-tables=FORCE
innodb-default-encryption-key-id=1


說明:
file_key_management.so : MariaDB Encryption的Plugin。
innodb-encrypt-log : 官方建議啟用,似乎比較安全。
innodb-encrypt-tables : [ON | OFF | FORCE],若設定成FORCE,建立table時設定ENCRYPTED=NO會建立失敗。


設定完後儲存,再將MariaDB重新啟動:
[root@jyc-blog ~]# systemctl restart mysql.service

測試

檢查是否有載入file_key_management plugin:
[root@jyc-blog ~]# mysql -u root -p -e "SHOW PLUGINS SONAME 'file_key_management.so';"
Enter password:
+---------------------+--------+------------+------------------------+---------+
| Name                | Status | Type       | Library                | License |
+---------------------+--------+------------+------------------------+---------+
| file_key_management | ACTIVE | ENCRYPTION | file_key_management.so | GPL     |
+---------------------+--------+------------+------------------------+---------+


查看plugin的各個參數:
[root@jyc-blog ~]# mysql -u root -p -e "show variables like '%encrypt%';"
Enter password:
+------------------------------------------------------+------------+
| Variable_name                                                 | Value      |
+-------------------------------------------------------+-----------+
| aria_encrypt_tables                                           | OFF        |
| encrypt_tmp_disk_tables                                  | OFF        |
| encrypt_tmp_files                                              | ON         |
| file_key_management_encryption_algorithm  | aes_cbc   |
| innodb_default_encryption_key_id                  | 1              |
| innodb_encrypt_log                                          | ON          |
| innodb_encrypt_tables                                      | FORCE   |
| innodb_encryption_rotate_key_age                  | 1              |
| innodb_encryption_rotation_iops                     | 100          |
| innodb_encryption_threads                               | 4              |
+-------------------------------------------------------+------------+


建立資料庫和資料表: 
[root@jyc-blog ~]# mysql -u root -p
Enter password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 14
Server version: 10.1.6-MariaDB MariaDB Server

Copyright (c) 2000, 2015, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> CREATE DATABASE encrypted;
Query OK, 1 row affected (0.00 sec)

MariaDB [(none)]> use encrypted;
Database changed
MariaDB [encrypted]> CREATE TABLE test (id INTEGER NOT NULL PRIMARY KEY, col1 VARCHAR(100)) ENGINE=Innodb ENCRYPTED=YES ENCRYPTION_KEY_ID=1;
Query OK, 0 rows affected (0.02 sec)


#查看table是不是有加密: 
MariaDB [encrypted]> SHOW TABLE STATUS ;
+-----------------------------------------------------------------+
| Create_options                                                               |
+-----------------------------------------------------------------+
| `ENCRYPTED`=YES `ENCRYPTION_KEY_ID`=1  |
+-----------------------------------------------------------------+

# 測試innodb-encrypt-tables=FORCE是否生效,將ENCRYPTED修改為NO:
MariaDB [encrypted]> ALTER test ENCRYPTED=NO;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'test ENCRYPTED=NO' at line 1












2015年7月15日 星期三

CentOS7 - 使用rvm安裝ruby環境

下載套件

[root@jyc-blog ~]# yum install gcc-c++ patch readline readline-devel zlib zlib-devel libyaml-devel libffi-devel openssl-devel make bzip2 autoconf automake libtool bison iconv-devel -y


安裝 RVM ( Ruby Version Manager )

下列指令可以安裝最新版的RVM,這兩行指令會自動下載所需的檔案並自動安裝: 
[root@jyc-blog ~]# gpg2 --keyserver hkp://keys.gnupg.net --recv-keys D39DC0E3

[root@jyc-blog ~]# curl -L get.rvm.io | bash -s stable


設定RVM環境

安裝完RVM後,要先輸入下列的指令設定RVM的環境: 

[root@jyc-blog ~]# source /etc/profile.d/rvm.sh

安裝Ruby

RVM可以安裝多個Ruby版本在同一台機器上,輸入下列的指令安裝你所需的Ruby版本 :

[root@jyc-blog ~]#  rvm install 2.2.2

或是你也可以安裝其它版本

[root@jyc-blog ~]# rvm install 1.9.3

設定預設要使用的Ruby版本


[root@jyc-blog ~]#  rvm use 2.2.2 --default 


查看目前Ruby的版本


[root@jyc-blog ~]#  ruby --version
ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux]



2015年7月9日 星期四

CentOS 7 設定PAM透過資料庫(MySQL、MariaDB)認證使用者身份 - pam_mysql & libnss_mysql


環境準備

在開始安裝之前,請先完成下列的步驟:
1. 安裝EPEL Repository,安裝步驟請參考這篇文章:
http://jyc-blog.blogspot.tw/2015/07/centos7-epel-repository.html

2. 關閉SELinux


下載套件

[root@jyc-blog ~]# yum groupinstall "Development Tools" -y
[root@jyc-blog ~]# yum install cyrus-sasl openssl mariadb mariadb-devel mariadb-server pam-devel libnss-mysql -y


編譯pam_mysql

pam_mysql的tarball檔可以到它的官方網站下載:

[root@jyc-blog ~]# cd /usr/local/src
[root@jyc-blog src]# wget http://prdownloads.sourceforge.net/pam-mysql/pam_mysql-0.7RC1.tar.gz
[root@jyc-blog src]# tar -zxvf pam_mysql-0.7RC1.tar.gz
[root@jyc-blog src]# cd pam_mysql-0.7RC1/
[root@jyc-blog src]# ./configure --with-pam-mods-dir=/usr/lib64/security  #指定pam module要存放到哪一個目錄底下
...
...省略...
...
config.status: creating Makefile
config.status: creating pam_mysql.spec
config.status: creating config.h
config.status: config.h is unchanged
config.status: executing default-1 commands

[root@jyc-blog src]# make install

#確認pam_mysql.so安裝成功
[root@jyc-blog src]# ls /usr/lib64/security/pam_mysql.so
/usr/lib64/security/pam_mysql.so


設定mysql

[root@jyc-blog ~]# systemctl start mariadb
[root@jyc-blog ~]# systemctl enable mariadb
[root@jyc-blog ~]# mysql_secure_installation

/usr/bin/mysql_secure_installation: line 379: find_mysql_client: command not found

NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
      SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!

In order to log into MariaDB to secure it, we'll need the current
password for the root user.  If you've just installed MariaDB, and
you haven't set the root password yet, the password will be blank,
so you should just press enter here.

Enter current password for root (enter for none): <ENTER>
OK, successfully used password, moving on...

Setting the root password ensures that nobody can log into the MariaDB
root user without the proper authorisation.

Set root password? [Y/n] Y
New password: PASSWORD
Re-enter new password: PASSWORD
Password updated successfully!
Reloading privilege tables..
 ... Success!


By default, a MariaDB installation has an anonymous user, allowing anyone
to log into MariaDB without having to have a user account created for
them.  This is intended only for testing, and to make the installation
go a bit smoother.  You should remove them before moving into a
production environment.

Remove anonymous users? [Y/n] Y
 ... Success!

Normally, root should only be allowed to connect from 'localhost'.  This
ensures that someone cannot guess at the root password from the network.

Disallow root login remotely? [Y/n] Y
 ... Success!

By default, MariaDB comes with a database named 'test' that anyone can
access.  This is also intended only for testing, and should be removed
before moving into a production environment.

Remove test database and access to it? [Y/n] Y
 - Dropping test database...
 ... Success!
 - Removing privileges on test database...
 ... Success!

Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.

Reload privilege tables now? [Y/n] Y
 ... Success!

Cleaning up...

All done!  If you've completed all of the above steps, your MariaDB
installation should now be secure.

Thanks for using MariaDB!



設定libnss-mysql

libnss-mysql提供三個設定檔的範例:

complex: 
/usr/share/doc/libnss-mysql-1.5/sample/complex/libnss-mysql-root.cfg
/usr/share/doc/libnss-mysql-1.5/sample/complex/libnss-mysql.cfg
/usr/share/doc/libnss-mysql-1.5/sample/complex/sample_database.sql

linux:
/usr/share/doc/libnss-mysql-1.5/sample/linux/libnss-mysql-root.cfg
/usr/share/doc/libnss-mysql-1.5/sample/linux/libnss-mysql.cfg
/usr/share/doc/libnss-mysql-1.5/sample/linux/sample_database.sql

minimal:
/usr/share/doc/libnss-mysql-1.5/sample/minimal/libnss-mysql-root.cfg
/usr/share/doc/libnss-mysql-1.5/sample/minimal/libnss-mysql.cfg
/usr/share/doc/libnss-mysql-1.5/sample/minimal/sample_database.sql

這三種範例之間的差異只有資料庫欄位的多寡,complex的欄位最多,因此可以設定的使用者資訊也最多。
minimal則只有username、password、group、uid和gid這些欄位。
linux的欄位就跟/etc/passwd的欄位設定一樣,此為套件預設值。


# 先複製一份sample sql,有一些地方需要修改
[root@jyc-blog ~]# cp /usr/share/doc/libnss-mysql-1.5/sample/linux/sample_database.sql /root/linux_sample_database.sql

#將TYPE=MyISAM從sample檔刪除,否則在匯入時會出現Syntax Error
[root@jyc-blog ~]# sed -i "s:TYPE=MyISAM::g" linux_sample_database.sql

[root@jyc-blog ~]# vim /root/linux_sample_database.sql

# line 23  設定資料庫名稱 ,如果有變動連下面有資料庫名稱的部份也要跟著修改
create database auth;
use auth;

# line 62 - 67 這部份是建立新使用者的sql範例
INSERT INTO users (username,gecos,homedir,password)
    VALUES ('jychen', 'Jheng-Yu Chen', '/home/jychen', ENCRYPT('jychen'));
INSERT INTO groups (name)
    VALUES ('jychen');
INSERT INTO grouplist (gid,username)
    VALUES (5000,'jychen');

# line 70 - 93 comment out. 這部份新增的資料庫使用者,只能查詢不能寫入,但我希望能透過passwd指令修改使用者的密碼,因此後面的使用者設定都使用root身份
#GRANT USAGE ON *.* TO `nss-root`@`localhost` IDENTIFIED BY 'rootpass';
#GRANT USAGE ON *.* TO `nss-user`@`localhost` IDENTIFIED BY 'userpass';
#
#GRANT Select (`username`, `uid`, `gid`, `gecos`, `homedir`, `shell`, `password`,
#              `lstchg`, `min`, `max`, `warn`, `inact`, `expire`, `flag`)
#             ON `auth`.`users`
#             TO 'nss-root'@'localhost';
#GRANT Select (`name`, `password`, `gid`)
#             ON `auth`.`groups`
#             TO 'nss-root'@'localhost';
#
#GRANT Select (`username`, `uid`, `gid`, `gecos`, `homedir`, `shell`)
#             ON `auth`.`users`
#             TO 'nss-user'@'localhost';
#GRANT Select (`name`, `password`, `gid`)
#             ON `auth`.`groups`
#             TO 'nss-user'@'localhost';
#
#GRANT Select (`username`, `gid`)
#             ON `auth`.`grouplist`
#             TO 'nss-user'@'localhost';
#GRANT Select (`username`, `gid`)
#             ON `auth`.`grouplist`
#             TO 'nss-root'@'localhost';



到目前為止,我們已經把資料庫和要匯入的sql檔案給設定好了,接下就把sql檔匯入資料庫 :

[root@jyc-blog ~]# mysql -u root -pPASSWORD < linux_sample_database.sql

#查看是否有匯入成功
[root@jyc-blog ~]# mysql -u root -pPASSWORD -e "use auth; select * from users;"
+----------+------+------+---------------+--------------+-----------+---------------+--------+-----+-------+------+-------+--------+------+
| username | uid  | gid  | gecos      | homedir      | shell     | passwor   | lstchg | min | max   | warn | inact | expire | flag |
+----------+------+------+---------------+--------------+-----------+---------------+--------+-----+-------+------+-------+--------+------+
| jychen   | 5000 | 5000 | Jheng-Yu Chen | /home/jychen | /bin/bash | 9OrIPVOVR0zk. | 1 | 0 | 99999 |    0 | 0 | -1 | 0 |
+----------+------+------+---------------+--------------+-----------+---------------+--------+-----+-------+------+-------+--------+------+



資料庫匯入完成後,再來就要修改libnss-mysql的設定檔,因為預設已經將設定檔放在/etc目錄底下,我們只需要修改這些設定檔就可以了:

[root@jyc-blog ~]# vim /etc/libnss-mysql.cfg

# line 34 - 39 modify
host        localhost
database    auth
username    root
password    PASSWORD
socket      /var/lib/mysql/mysql.sock
port        3306


[root@jyc-blog ~]# vim /etc/libnss-mysql-root.cfg

# line 1 modify
username    root
password    PASSWORD


再來要修改Name Service Switch的設定檔,讓它能夠讀取MySQL的認證資料:

[root@jyc-blog ~]# vim /etc/nsswitch.conf

# line 33 - 35 modify
passwd:     files sss mysql
shadow:     files sss mysql
group:      files sss mysql



設定pam_mysql

詳細的設定可以參考官方的Document:
[root@jyc-blog ~]# vim /etc/pam_mysql.conf

#add following
users.host=/var/lib/mysql/mysql.sock
users.db_user=root
users.db_passwd=PASSWORD
users.database=auth
users.table=users
users.user_column=username
users.password_column=password
users.password_crypt=1
verbose=0


修改PAM


[root@jyc-blog ~]# vim /etc/pam.d/system-auth

#插入下面五行(綠色字)
auth        required      pam_env.so
auth        sufficient    pam_unix.so nullok try_first_pass
auth        requisite     pam_succeed_if.so uid >= 1000 quiet_success
auth        sufficient  pam_mysql.so    config_file=/etc/pam_mysql.conf
auth        required      pam_deny.so

account     required      pam_unix.so
account     sufficient    pam_localuser.so
account     sufficient    pam_succeed_if.so uid < 1000 quiet
account     sufficient  pam_mysql.so    config_file=/etc/pam_mysql.conf
account     required      pam_permit.so

password    requisite     pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type=
password    sufficient    pam_unix.so sha512 shadow nullok try_first_pass use_authtok
password     sufficient  pam_mysql.so    config_file=/etc/pam_mysql.conf
password    required      pam_deny.so

session     optional      pam_keyinit.so revoke
session     required      pam_limits.so
-session     optional      pam_systemd.so
#因為是透過資料庫新增使用者,所以需要手動建立使用者的家目錄,但自己手動建立還要設定權限等等,因此這邊以PAM的方式,讓使用者在登入的同時自動建立家目錄:
session     optional      pam_mkhomedir.so umask=0077
session     [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session     sufficient  pam_mysql.so    config_file=/etc/pam_mysql.conf
session     required      pam_unix.so




測試

[root@jyc-blog ~]# id jychen
uid=5000(jychen) gid=5000(jychen) groups=5000(jychen)

[root@jyc-blog ~]# ssh jychen@127.0.0.1
The authenticity of host '127.0.0.1 (127.0.0.1)' can't be established.
ECDSA key fingerprint is 3e:95:18:bb:65:98:ff:4b:cb:15:34:ee:b1:f7:22:3f.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '127.0.0.1' (ECDSA) to the list of known hosts.
jychen@127.0.0.1's password:  PASSWORD
Creating directory '/home/jychen'.
Last login: Thu Jul  9 23:52:36 2015 from localhost
[jychen@jyc-blog ~]$ exit


#用passwd指令修改密碼
[root@jyc-blog ~]# mysql -u root -pPASSWORD -e "use auth ; select password from users where uid=5000"
+---------------------+
|       password       |
+---------------------+
| 1uQQ2ugLqZa.A |
+---------------------+

[root@jyc-blog ~]#  passwd jychen
Changing password for user jychen.
New password: PASSWORD
Retype new password: PASSWORD
passwd: all authentication tokens updated successfully.

[root@jyc-blog ~]# mysql -u root -pPASSWORD -e "use auth ; select password from users where uid=5000"
+-------------------------------------------------------+
|                              password                             |
+-------------------------------------------------------+
| $1$WRJqJIP1$U3nAswi3F6RJtGtGD0OyW. |
+-------------------------------------------------------+
#從第一次和第二次Select出來的password資料,可以看出密碼有被修改成功。

Enjoy!






可能會遇到的錯誤

[root@jyc-blog pam_mysql-0.7RC1]# ./configure --with-pam-mods-dir=/usr/lib64/security
...
...省略...
...
checking if /usr /usr/local /usr/mysql /opt/mysql is a mysql_config script... no
checking mysql_config availability in /usr/bin... no
checking mysqlclient availability in /usr/lib... no
checking mysqlclient availability in /usr/lib/mysql... no
checking mysql headers availability in /usr/include... no
checking mysql headers availability in /usr/include/mysql... no
checking mysql_config availability in /usr/local/bin... no
checking mysqlclient availability in /usr/local/lib... no
checking mysqlclient availability in /usr/local/lib/mysql... no
checking mysql headers availability in /usr/local/include... no
checking mysql headers availability in /usr/local/include/mysql... no
checking mysql_config availability in /usr/mysql/bin... no
checking mysqlclient availability in /usr/mysql/lib... no
checking mysqlclient availability in /usr/mysql/lib/mysql... no
checking mysql headers availability in /usr/mysql/include... no
checking mysql headers availability in /usr/mysql/include/mysql... no
checking mysql_config availability in /opt/mysql/bin... no
checking mysqlclient availability in /opt/mysql/lib... no
checking mysqlclient availability in /opt/mysql/lib/mysql... no
checking mysql headers availability in /opt/mysql/include... no
checking mysql headers availability in /opt/mysql/include/mysql... no
configure: error: Cannot locate mysql client library. Please check your mysql installation.

#解決方式 : 安裝mariadb-devel
[root@jyc-blog pam_mysql-0.7RC1]# yum install mariadb-devel -y



[root@jyc-blog pam_mysql-0.7RC1]# ./configure --with-pam-mods-dir=/usr/lib64/security
...
...省略...
...
configure: error: Cannot find pam headers. Please check if your system is ready for pam module development.

#解決方式 : 安裝pam-devel
[root@jyc-blog pam_mysql-0.7RC1]# yum install pam-devel -y



[root@jyc-blog pam_mysql-0.7RC1]# ./configure
...
...省略...
...
configure: error: Cannot find pam headers. Please check if your system is ready for pam module development.

#解決方式 : 指定pam module的存放目錄
[root@jyc-blog pam_mysql-0.7RC1]# ./configure --with-pam-mods-dir=/usr/lib64/security



2015年7月1日 星期三

CentOS 7 安裝 Proftpd 同時提供 FTP、FTPs與SFTP服務

這次實驗的目的有三個:

  1. Server同時提供FTP、FTPs與SFTP的服務。
  2. 支援chroot。
  3. 同一個使用者登入不同的服務,所看到的檔案資料都要相同。

ProFTPd是「Professional FTP daemon」的縮寫,與vsFTPd 一樣都是強調安全性的 FTP 伺服軟體,vsFTPd是目前最常用的FTP軟體,那為什麼不用vsFTPd就好了呢?
原因在於vsFTPd不支援SFTP服務,因此要另外使用SSHd的SFTP模組,但SSHd的SFTP模組如果要支援chroot功能,所有SFTP使用者都必須加到同一個群組,且chroot的資料夾擁有者一定要是root,因此在權限設定上有一定的限制。
ProFTPd的設定方式與網頁伺服器Apache非常類似,一樣有VirtualHost與module的概念,ProFTPd本身就有支援SFTP的module,因此不需要另外使用SSHd的SFTP模組,也不像它有權限與群組上的限制,在權限控管上比較靈活,另外因為不需要同時設定兩個不同的軟體(vsFTPd與SSHd),在設定上也相對單純。

安裝

在安裝proftpd之前,要先安裝EPEL Repository,安裝步驟請參考這篇文章:

[root@proftpd1 ~]# yum install proftpd -y  
[root@proftpd1 ~]# getenforce         #確認SELinux是關閉狀態
Disabled


設定FTP服務

/etc/proftpd.conf 是ProFTPd的主要設定檔。
[root@proftpd1 ~]# vim /etc/proftpd.conf

#line 77 modify
ServerName "proftpd1"    #記得要將proftpd1加到/etc/hosts中,否則會出現錯誤!!

#line 81 add
Port 21
PassivePorts 40000 45000     #因為需要設定防火牆,所以使用Passive Mode


設定FTPs服務

#建立Self-Signed certificate
 [root@proftpd1 ~]# openssl req -x509 -nodes -newkey rsa:2048 -keyout /etc/pki/tls/certs/proftpd.pem -out /etc/pki/tls/certs/proftpd.pem
Generating a 2048 bit RSA private key
..+++
.......+++
writing new private key to '/etc/pki/tls/certs/proftpd.pem'
-----
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]:TW
State or Province Name (full name) []:Taiwan
Locality Name (eg, city) [Default City]:Hsinchu    
Organization Name (eg, company) [Default Company Ltd]:JYC
Organizational Unit Name (eg, section) []:JYC
Common Name (eg, your name or your server's hostname) []:proftpd1
Email Address []:fishgo65@gmail.com

#修改設定檔

[root@proftpd1 ~]# vim /etc/proftpd.conf

# near line 294 modify
#<IfDefine TLS>
  TLSEngine                              on
  TLSRequired                           off    #如果要強制使用FTPs則改為on
  TLSRSACertificateFile           /etc/pki/tls/certs/proftpd.pem
  TLSRSACertificateKeyFile    /etc/pki/tls/certs/proftpd.pem
  TLSCipherSuite                      ALL:!ADH:!DES
  TLSOptions                             NoCertRequest
  TLSVerifyClient                     off
  #TLSRenegotiate                    ctrl 3600 data 512000 required off timeout 300
  TLSLog                                   /var/log/proftpd/tls.log
#  <IfModule mod_tls_shmcache.c>
#          TLSSessionCache            shm:/file=/var/run/proftpd/sesscache
#  </IfModule>
#</IfDefine>


設定SFTP服務

[root@proftpd1 ~]# vim /etc/proftpd.conf

#near line 210 uncomment
LoadModule mod_sftp.c

#near line 214 uncomment
LoadModule mod_sftp_pam.c

#near line 429 add
<VirtualHost 0.0.0.0>
        Port 2221
        <IfModule mod_sftp.c>
            SFTPEngine on
            SFTPLog /var/log/proftpd/sftp.log
            SFTPHostKey /etc/ssh/ssh_host_rsa_key    #權限必須為600,否則會出現錯誤
            SFTPCompression delayed
        </IfModule>
</VirtualHost>


#修改權限
[root@proftpd1 ~]# chmod 600 /etc/ssh/ssh_host_rsa_key

啟動ProFTPd

[root@proftpd1 ~]# systemctl restart proftpd.service
[root@proftpd1 ~]# systemctl enable proftpd.service
ln -s '/usr/lib/systemd/system/proftpd.service' '/etc/systemd/system/multi-user.target.wants/proftpd.service'

設定防火牆

#確認firewalld為Stop的狀態
[root@proftpd1 ~]# systemctl status firewalld
firewalld.service
   Loaded: masked (/dev/null)
   Active: inactive (dead) since Thu 2015-06-11 17:02:09 CST; 2 weeks 6 days ago
 Main PID: 1218 (code=exited, status=0/SUCCESS)

Jun 05 13:38:50 proftpd1 systemd[1]: Started firewalld - dynamic firewall daemon.
Jun 11 17:02:08 proftpd1 systemd[1]: Stopping firewalld.service...
Jun 11 17:02:09 proftpd1 systemd[1]: Stopped firewalld.service.
Hint: Some lines were ellipsized, use -l to show in full.

#讓iptables載入ftp模組
[root@proftpd1 ~]# vim /etc/sysconfig/iptables-config
#line 6 modify
IPTABLES_MODULES="ip_nat_ftp ip_conntrack_ftp"

#啟動iptables
[root@proftpd1 ~]# systemctl start iptables
[root@proftpd1 ~]# systemctl enable iptables
[root@proftpd1 ~]# vim iptables.sh
# add
iptables -F
iptables -X
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P INPUT DROP
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -p icmp -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 21 -j ACCEPT
iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 2221 -j ACCEPT
iptables -A INPUT -p tcp -m state --state NEW -m tcp -m multiport --dports 40000:45000 -j ACCEPT
iptables -A INPUT -j REJECT --reject-with icmp-host-prohibited
iptables -A FORWARD -j REJECT --reject-with icmp-host-prohibited
iptables-save > /etc/sysconfig/iptables
[root@proftpd1 ~]# sh iptables.sh
[root@proftpd1 ~]# systemctl restart iptables

測試服務

#建立使用者
[root@proftpd1 ~]# useradd ftpuser -s /sbin/nologin
[root@proftpd1 ~]# echo 'ftpuser' | passwd --stdin ftpuser
更改使用者 ftpuser 的密碼。
passwd:所有驗證 token 都已成功更新。

#建立測試檔案
[root@proftpd1 ~]# touch ftptest

#測試FTP與SFTP
[root@proftpd1 ~]# yum install ftp sftp -y
[root@proftpd1 ~]# ftp proftpd1 21
ftp proftpd1 21
Connected to proftpd1 (127.0.0.1).
220 FTP Server ready.
Name (proftpd1:root): ftpuser
331 Password required for ftpuser
Password: ftpuser
230 User ftpuser logged in
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> put ftptest
local: ftptest remote: ftptest
227 Entering Passive Mode (127,0,0,1,175,71).
150 Opening BINARY mode data connection for ftptest
226 Transfer complete
ftp> ls
227 Entering Passive Mode (127,0,0,1,174,242).
150 Opening ASCII mode data connection for file list
-rw-r--r--   1 ftpuser  ftpuser         0 Jul  1 12:24 ftptest
226 Transfer complete
ftp> quit

[root@proftpd1 ~]# sftp -P 2221 ftpuser@proftpd1
The authenticity of host '[proftpd1]:2221 ([127.0.0.1]:2221)' can't be established.
RSA key fingerprint is 20:ef:e8:1a:89:1f:22:27:8c:f5:46:8e:2b:da:81:fc.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[proftpd1]:2221' (RSA) to the list of known hosts.
Password: ftpuser
Connected to proftpd1.
sftp> ls
ftptest       #確定不同服務看到的檔案資料都相同
sftp> quit




可能會遇到的錯誤

#沒有將/etc/ssh/ssh_host_rsa_key的權限修改為600
[root@proftpd1 ~]# systemctl status proftpd.service -l
proftpd.service - ProFTPD FTP Server
   Loaded: loaded (/usr/lib/systemd/system/proftpd.service; enabled)
   Active: failed (Result: exit-code) since 四 2015-07-02 14:15:45 CST; 12s ago
  Process: 3876 ExecStart=/usr/sbin/proftpd $PROFTPD_OPTIONS (code=exited, status=1/FAILURE)
 Main PID: 1073 (code=exited, status=0/SUCCESS)

 7月 02 14:15:45 proftpd1 systemd[1]: Starting ProFTPD FTP Server...
 7月 02 14:15:45 proftpd1 proftpd[3876]: 2015-07-02 14:15:45,412 proftpd1 proftpd[3876]: fatal: SFTPHostKey: unable to use '/etc/ssh/ssh_host_rsa_key' as host key, as it is group- or world-accessible on line 434 of '/etc/proftpd.conf'
 7月 02 14:15:45 proftpd1 systemd[1]: proftpd.service: control process exited, code=exited status=1
 7月 02 14:15:45 proftpd1 systemd[1]: Failed to start ProFTPD FTP Server.
 7月 02 14:15:45 proftpd1 systemd[1]: Unit proftpd.service entered failed state.
#解決方式
[root@proftpd1 ~]# chmod 600 /etc/ssh/ssh_host_rsa_key

2015年3月3日 星期二

CentOS7 語系

可以透過這幾個指令查看目前的語系設定

# echo $LANG
en_US.UTF-8

# locale
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=

如果要變更語系可以用這種方式:

# LANG=zh_TW.UTF-8

再用上述的查詢指令可以zh_TW.UTF-8,但這個設定方式只能存在目前這個Session,也就是下次重開或是重新登入又會變成原本沒有變更的語系設定。

因此要讓設定永久生效,可以使用下列幾種方式:

針對個別使用者 - 修改~/.bashrc
# vim ~/.bashrc
export LANG=zh_TW.UTF-8

針對所有的系統使用者 - 修改/etc/bashrc
# vim /etc/bashrc
export LANG=zh_TW.UTF-8

或是使用localectl這個指令修改語系
# localectl set-locale LANG=zh_TW.UTF-8


另外針對非英語系的語系,還需要額外安裝語言套件,我們可以透過YUM來安裝,語法與說明如下:

# yum langavailable                  #查詢目前可供安裝的語言套件
# yum langlist                           #查詢目前系統已經安裝的語言套件
# yum langinstall <Package_name>      #安裝語言套件,「套件名稱」的位置要由yum langavailable顯示出來的字串替代。




2015年2月26日 星期四

Ubuntu 防止螢幕鎖定

不像Windows環境,在開啟全螢幕模式後會自動防止螢幕鎖定,所以在Ubuntu看影片時都要時常動一下滑鼠才不會鎖定螢幕,不然每次鎖定後都還要再輸入一次密碼,這實在是很惱人的一件事,因此這篇文章要介紹一個ubuntu軟體「Caffeine」。

Caffeine(咖啡因),就如同它字面上的意思,它可以幫助你的電腦保持清醒(笑),當你用全螢幕模式在看影片時,它能防止進入螢幕鎖定模式或螢幕保護程式,不需要再敲一次密碼解鎖或一直動滑鼠。



安裝步驟

目前Caffeine(2015/02/26)只支援到Ubuntu 14.04版本,所以下面會有兩種不同的安裝方式,分別是14.04之前的版本與14.04之後的版本。

  • Ubuntu 14.04版之前的版本

Ubuntu 14.04之前的版本可以用apt的方式安裝,首先要加入Caffeine的ppa Repository:
[jyc@blogger] $ sudo add-apt-repository ppa:caffeine-developers/ppa
[jyc@blogger] $ sudo apt-get update
[jyc@blogger] $ sudo apt-get install caffeine


  • Ubuntu 14.04版之後的版本
Ubuntu 14.04之後的版本因為沒有在它的ppa Repository裡,所以要直接下載它的安裝檔:


到這個網址下載「https://launchpad.net/~caffeine-developers/+archive/ubuntu/ppa/+packages」,目前最新版本是2.8.3,所以要下載caffeine_2.8.3_all.deb這個檔案,下載下來後直接安裝就可以了。


操作說明

在Caffeine2.8.3的版本,它改成在背景常駐執行,意思就是它會自動偵測程式是不是有開啟全螢幕模式,可以透過這行指令確認它在背景執行:

[jyc@blogger] $ sudo ps aux | grep caffeine
jyc    2596  2.9  0.2 456040 42632 ?        Sl   20:30   0:00 /usr/bin/python3 /usr/bin/caffeine
jyc    2895  0.0  0.0  13688  2092 pts/2    S+   20:30   0:00 grep --color=auto caffeine

雖然它每次重開機就會自動啟動,但如果發現它沒有在背景執行,我們也可以手動啟動它,在「附屬應用」底下可以找到「Caffeine」的icon,點一下再用上述的指令確認它有在執行。



相信你們也發現在「Caffeine」的下面還有一個叫「Caffeine Indicator」的東西,它可以讓你自己決定什麼時候要防止進入螢幕鎖定模式,就如同之前說過的,「Caffeine」是"自動"在背景偵測全螢幕模式,而「Caffeine Indicator」則是"手動"防止進入螢幕鎖定模式。

點擊它之後就能在系統工具列上看到它的icon,再點「Activate」就能讓你的電腦不管在任何時候都能保持清醒啦,如果要取消點「Deactivate」就行啦。









2015年2月25日 星期三

Ubuntu 14.10與嘸蝦米 - 使用fcitx

在Ubuntu 14.10版本,預設是以ibus作為輸入法,但ibus本身並沒有嘸蝦米的table,因此需要下載table再把它format成ibus看得懂的db,雖然可以正常使用,但從網路上下載的嘸蝦米table品質參差不齊,常常會出現亂碼和字打不出來的窘境,而且ibus的輸入法切換用得很不習慣,所以接下來要介紹另一個輸入法軟體「fcitx」。


Fcitx,現英文全稱「Flexible Input Method Framework」,中文名稱為「小企鵝輸入法」。

支援下列的輸入法:
fcitx-chewing: 新酷音
fcitx-sunpinyin: 双拼
fcitx-anthy: 使用Anthy引擎的日文輸入法
fcitx-cloudpinyin: 為所有拼音引擎提供雲拼音支援
fcitx-googlepinyin: 移植自Android的Google拼音支援
fcitx-handwriting: Zinnia作為後端的手寫支援
fcitx-keyboard: 採用系統鍵盤布局作為輸入法,以及提供拼寫檢查
fcitx-libpinyin: libpinyin 為後端的漢語拼音支援
fcitx-m17n: 使用m17n-db的多語言輸入法
fcitx-mozc: 使用mozc引擎的日文輸入法
fcitx-pinyin: 漢語拼音支援
fcitx-sunpinyin: Sunpinyin 為後端的漢語拼音支援


另外還支援table類型的輸入法,像是:
fcitx-table-boshiamy: 嘸蝦米
fcitx-table-cangjie-big: 倉頡大字集
fcitx-table-zhengma-large: 鄭碼大字集
fcitx-table-wubi-large: 五筆大字集
fcitx-table-easy-big: 輕鬆大詞庫

這邊可以看到fcitx在它的Repository裡已經提供嘸蝦米的table,因為就不需要再去網路上下載那些品質參差不齊的table,接下來介紹在fcitx在Ubuntu 14.10的安裝步驟。

安裝步驟

先加入fcitx開發團隊的repository:
sudo add-apt-repository ppa:fcitx-team/nightly
sudo apt-get update

安裝fcitx與嘸蝦米table:
sudo apt-get install fcitx fcitx-m17n
sudo apt-get install fcitx-table-boshiamy        #安裝嘸蝦米Table


系統設定

先到「系統設定值」,選「語言支援」,在「鍵盤輸入法系統」底下選擇 「fcitx」。




選完之後可以看到在系統工作列,還是存在預設的ibux輸入法ICON,


在ICON上點右鍵選擇「文字輸入設定」,並且把「在選單列顯示目前輸入來源」的勾勾取消掉。


接下來只要重開機或是重新登入,就可以在系統工具列上看到fcitx的ICON嘍!


其它參考資料:



2015年2月24日 星期二

在Ubuntu 14.10_amd64 上使用 Fortinet SSL VPN Client for Linux

最近工作上需要在Ubuntu上用SSL VPN,但是在安裝的時候遇到不少問題,像是我的Ubuntu14.10是64位元的作業系統, 而Fortinet SSL VPN Client for Linux因為很久沒更新了只支援32位元,所以很多Google出來的解決方式都不能用。

Forticlient SSL VPN for Linux的下載連結:
forticlientsslvpn_linux_4.0.2254.tar.gz (1.6MB)
forticlientsslvpn_linux_4.4.2287.tar.gz (4.1MB)
forticlientsslvpn_linux_4.4.2297.tar.gz (3.9MB)

這三個版本都有測試過是可以用的。


安裝VPN Client之前請先解壓縮,並執行「forticlientsslvpn」這個檔案:
[jyc@blogger] $ tar -zxvf forticlientsslvpn_linux_4.0.2254.tar.gz
[jyc@blogger] $ cd forticlientsslvpn
[jyc@blogger] $ sudo ./forticlientsslvpn
sudo: unable to execute ./forticlientsslvpn: No such file or directory

這邊可以看到執行了forticlientsslvpn後,系統確說找不到這個檔案,但是檔案明明就在那裡,檔案權限中也有可執行的權限,原因就如同一開始所說的,因為這個版本的forticlient是32位元版本,而我的系統則是64位元的版本,因此需要安裝32位元版本的Library:

sudo apt-get install libgtk2.0-0:i386 libsm6:i386 libstdc++6:i386

安裝完後再執行一次:

[jyc@blogger] $ sudo ./forticlientsslvpn
(forticlientsslvpn:11015): Gtk-WARNING **: 無法在 module_path 中找出佈景主題引擎:‘murrine’,
Gtk-Message: Failed to load module "canberra-gtk-module"

雖然還是有出現錯誤,但它還是可以正常執行,如下圖,它要你同意License規定,輸入Yes。


輸入完後就可以看到這個視窗。


再回到之前的錯誤訊息,系統說找不到murrine這個佈景主題,可以透過安裝這個套件解決:
[jyc@blogger] $ sudo apt-get install gtk2-engines-murrine:i386

第二個錯誤訊息則是說無法載入canberra-gtk-module這個模組,一樣可以用安裝32位元版的套件解決:
[jyc@blogger] $ sudo apt-get install libcanberra-gtk-module:i386


最後的視窗則長這樣,跟找不到佈景主題的時候相比是有比較漂亮點 :D



2015年2月12日 星期四

linux 間接指定變數(Indirect Variable)


一般來說在Linux裡,直接指定變數(direct variable)有三種方式:

1. 儲存直接指定的值,例如:
[root@blogger] # VAR="assigning value directly"
[root@blogger] # echo $VAR
assigning value directly

2. 儲存指令的輸出結果,例如:
[root@blogger] # VAR=$(uname -a)
[root@blogger] # echo $VAR
Linux blogger2.6.32-431.29.2.el6.x86_64 #1 SMP Tue Sep 9 21:36:05 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

3. 儲存計算結果,例如:
[root@blogger] # VAR=$(( 1 + 1 ))
[root@blogger] # echo $VAR
2

上述的三種方式或許你事先不知道變數的值,但是你一定會知道變數的名稱,例如上面的VAR,就是你一定要知道的變數名稱,才能使用VAR的值。

但是在某些情況下,我們不一定會事先知道變數的名稱,或是要讓程式動態產生變數名稱,這時候就可以用Linux的「eval」指令。

範例:
產生十個uid,
[root@blogger] # vim eval_eg.sh
1 #!/bin/bash
2
3 for (( uid=1; uid<=10; uid=uid+1 ))
4 do
5         suffix="name"
6         eval user_${uid}_${suffix}=user$uid                    => user_1_name=user1
7         eval echo -n '$user'_${uid}_${suffix}: uid=$uid',\ '   => $user_1_name
8         suffix="home"
9         eval user_${uid}_${suffix}="/home/user$uid"
10        eval echo home='$user'_${uid}_${suffix}
11 done