2016年10月31日 星期一

[ 常見問題 ] 在 container 裡面存取 host 檔案遇到 Permission denied?

Source From Here
Question
最近在用 docker 建立專案編譯的環境,在 docker run 裡用 -v 指令將本地端的 ~/p4 目錄掛載到 container 裡的 /p4 使用,好讓 container 裡面可以存取到外面的原始碼:
# docker run -it -v ~/p4:/p4 testuser/build_prj /bin/bash

檔案掛載沒有問題,但是進到 container 裡面想要 ls 一下,卻出現了 Permission denied 的問題:
root@b9f5a339508b /p4 # ls
ls: cannot open directory .: Permission denied

查了一下,原來是 SELinux 的影響:

How-To
要解決這個問題,在 -v 參數的最後面,加上 :z 或是 :Z,分別代表的是:
* :z 會 label 這個目錄,使其可以被多個 container 共用
* :Z 會 label 這個目錄,使其可以被目前的 container 使用 (其他 container 不能共用)

加上 :z 或 :Z 後,docker 會幫我們 label 由這個目錄掛載起來的 volume,因此 container 裡面就不會被 SELinux 阻擋存取 volume 的資料了. 舉例來說,我可以把一開始的 docker run 指令改成下面這樣:
# docker run -it -v ~/p4:/p4:z testuser/build_prj /bin/bash

接著在 container 裡面,就能成功的存取 /p4 的檔案了:
root@fe90d2001d04 /p4 # ll

total 260
drwxrwxr-x. 9 1000 1000 4096 Sep 17 09:26 Common
-r--r--r--. 1 1000 1000 13415 Oct 1 16:40 Makefile


2016年10月28日 星期五

[ InAction Note ] Ch5. Message Storage - The JDBC message store

Preface: 
The flexibility of the ActiveMQ pluggable message store API allows for many different implementation choices. The oldest and more common store implementation uses JDBC for messaging persistence. The most common reason why so many organizations choose the JDBC message store is because they already have expertise administering relational databases. JDBC persistence is definitely not superior in performance to the aforementioned message store implementations. The fact of the matter is that many businesses have invested in the use of relational databases so they prefer to make full use of them. 

But the use of a shared database is particularly useful for making a redundant master/slave topology out of multiple brokers. When a group of ActiveMQ brokers is configured to use a shared database, they’ll all try to connect and grab a lock in the lock table, but only one will succeed and become the master. The remaining brokers will be slaves, and will be in a wait state, not accepting client connections until the master fails. This is a common deployment scenario for ActiveMQ, which will be covered in more detail in chapter 10. 

When using the JDBC message store, the default JDBC driver used in ActiveMQ is Apache Derby. But many other relational databases are supported. 

Databases supported by the JDBC message store: 
This isn’t an exhaustive list, the JDBC store has been shown to operate with the following relational databases: 
* Apache Derby
* MySQL
* PostgreSQL
* Oracle
* SQL Server
* Sybase
* Informix
* MaxDB

Some users prefer to use a relational database for message persistence simply because of the ability to query the database to examine messages. The following sections will discuss this topic. 

The JDBC message store schema: 
The JDBC message store uses a schema consisting of three tables. Two of the tables are used to hold messages, and the third is used as a lock table to ensure that only one ActiveMQ broker can access the database at one time. Here’s a detailed breakdown of these tables. 

The message table, shown in table 5.3, is by default named ACTIVEMQ_MSGS and is defined as follows. 
 

Messages are broken down and stored into the ACTIVEMQ_MSGS table for both queues and topics. 

There’s a separate table for holding durable subscriber information and an ID to the last message the durable subscriber received. This information is held in the ACTIVEMQ_ACKS table, which is shown in table 5.4. 
 

For durable subscribers, the LAST_ACKED_ID sequence is used as a simple pointer into the ACTIVEMQ_MSGS and enables messages for a particular durable subscriber to be easily selected from the ACTIVEMQ_MSGS table. 

The lock table, called ACTIVEMQ_LOCK, is used to ensure that only one ActiveMQ broker instance can access the database at one time. If an ActiveMQ broker can’t grab the database lock, that broker won’t initialize fully, and will wait until the lock becomes free, or it’s shut down. The table structure of the lock table is defined in table 5.5. 
 

Configuring the JDBC message store: 
Configuring the default JDBC message store is straightforward and the default JDBC store uses Apache Derby in the broker configuration as shown: 


The preceding configuration sets the persistence adaptor for the ActiveMQ broker to be the JDBC message store (which uses Apache Derby by default) and sets the data directory to be used by the embedded Apache Derby instance. 


One of the key properties on the JDBC persistence adapter (the interface onto the JDBC message store) is the dataSource property. This property defines a factory from which connections to a relational database are created. Configuring the dataSource object enables the JDBC persistence adaptor to use physical databases other than the default. Here’s an example of an ActiveMQ configuration for the JDBC message store using the MySQL database: 


The preceding example uses the Apache Commons DBCP BasicDataSource to wrap the MySQL JDBC driver for connection pooling. In the example, the driverClassName is the name of the JDBC driver to use. Some properties that you can configure are passed directly to the database driver itself. For example, maxActive is a property for the MySQL database connector, which tells the database how many active connections to hold open at one time. 


Just as a point of comparison, here’s an example of a configuration to use the Oracle database: 

This example uses the Apache Commons DBCP BasicDataSource to wrap the Oracle JDBC driver for connection pooling. 


Using the JDBC message store with the ActiveMQ journal: 
Though the performance of the JDBC message store isn’t wonderful, it can be improved through the use of the ActiveMQ journal. The journal ensures the consistency of JMS transactions. Because it incorporates fast message writes with caching technology, it can significantly improve the
performance of the ActiveMQ broker


Here’s an example configuration using the journal with JDBC (aka journaled JDBC). In this case, Apache Derby is being used. 


The journal can be used with any JDBC datasource, but it’s important to know when it should and shouldn’t be used. 


The journal offers considerable performance advantages over the use of a standard JDBC message store, especially when the JDBC database is co-located on the same machine as the ActiveMQ broker. The only time when it’s not possible to use the journal is in a shared database master/slave configuration. Because messages from the master may be stored locally in the journal before they’ve been committed to the database, using the journal in this configuration could lead to lost messages if the master failed because the journal isn’t replicated.

2016年10月24日 星期一

[Linux 文章收集] How To Set Up a Basic Iptables Firewall on Centos 6

Source From Here 
Preface 
This article will show how to create a simple firewall on a Centos VPS (Virtual Private Server). It will only open up ports that we want and close up other services. I will also show how to prevent simpler attacks, and how to let yourself back in to the VPS if you deny access to yourself by accident. The tutorial is not by any means exhaustive and only shows how to open up a few incoming ports: for apache, SSH and email and close all the others. We will not be blocking any outgoing traffic, and only create a few most common rules to block the usual scripts and bots that look for vulnerable VPS. 

iptables is a simple firewall installed on most linux distributions. The linux manual page for iptables says it is an administration tool for IPv4 packet filtering and NAT, which, in translation, means it is a tool to filter out and block Internet traffic. iptables firewall is included by default in Centos 6.4 linux images provided by DigitalOcean. We will set up firewall one by one rule. To simplify: a firewall is a list of rules, so when an incomming connection is open, if it matches any of the rules, this rule can accept that connection or reject it. If no rules are met, we use the default rule. 
Note: 
This tutorial covers IPv4 security. In Linux, IPv6 security is maintained separately from IPv4. For example, "iptables" only maintains firewall rules for IPv4 addresses but it has an IPv6 counterpart called "ip6tables", which can be used to maintain firewall rules for IPv6 network addresses.

If your VPS is configured for IPv6, please remember to secure both your IPv4 and IPv6 network interfaces with the appropriate tools. For more information about IPv6 tools, refer to this guide: How To Configure Tools to Use IPv6 on a Linux VPS 

Decide which ports and services to open 
To start with, we want to know what services we want to open to public. Let's use the typical web-hosting server: it is a web and email server, and we also need to let ourselves in by SSH server. First, we want to leave SSH port open so we can connect to the VPS remotely: that is port 22; Also, we need port 80 and 443 (SSL port) for web traffic. For sending email, we will open port 25 (regular SMTP) and 465 (secure SMTP). To let users receive email, we will open the usual port 110 (POP3) and 995 (secure POP3 port). 


Additionally, we'll open IMAP ports, if we have it installed: 143 for IMAP, and 993 for IMAP over SSL.Note: It is recommended to only allow secure protocols, but that may not be an option, if we cannot influence the mail service users to change their email clients. 

Block the most common attacks 
DigitalOcean VPSs usually come with the empty configuration: all traffic is allowed. Just to make sure of this, we can flush the firewall rules - that is, erase them all: 
// -F, --flush [chain]: Flush the selected chain (all the chains in the table if none is given). This is equivalent to deleting all the rules one by one.
# iptables -F

We can then add a few simple firewall rules to block the most common attacks, to protect our VPS from script-kiddies. We can't really count on iptables alone to protect us from a full-scale DDOS or similar, but we can at least put off the usual network scanning bots that will eventually find our VPS and start looking for security holes to exploit. First, we start with blocking null packets. 
// -p, --protocol protocol: The specified protocol can be one of tcp, udp, udplite, icmp, icmpv6,esp, ah, sctp, mh or the special keyword "all"
// -j, --jump target: This specifies the target of the rule; i.e., what to do if the packet matches it.

# iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
# iptables --list
Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP tcp -- anywhere anywhere tcp flags:FIN,SYN,RST,PSH,ACK,URG/NONE
...

We told the firewall to take all incoming packets with tcp flags NONE and just DROP them. Null packets are, simply said, recon packets. The attack patterns use these to try and see how we configured the VPS and find out weaknesses. The next pattern to reject is a syn-flood attack
# iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
# iptables --list
Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP tcp -- anywhere anywhere tcp flags:FIN,SYN,RST,PSH,ACK,URG/NONE
DROP tcp -- anywhere anywhere tcp flags:!FIN,SYN,RST,ACK/SYN state NEW
...

Syn-flood attack means that the attackers open a new connection, but do not state what they want (ie. SYN, ACK, whatever). They just want to take up our servers' resources. We won't accept such packages. Now we move on to one more common pattern: XMAS packets, also a recon packet. 
# iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
# iptables --list
Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP tcp -- anywhere anywhere tcp flags:FIN,SYN,RST,PSH,ACK,URG/NONE
DROP tcp -- anywhere anywhere tcp flags:!FIN,SYN,RST,ACK/SYN state NEW
DROP tcp -- anywhere anywhere tcp flags:FIN,SYN,RST,PSH,ACK,URG/FIN,SYN,RST,PSH,ACK,URG
...

We have ruled out at least some of the usual patterns that find vulnerabilities in our VPS. 

Open up ports for selected services 
Now we can start adding selected services to our firewall filter. The first such thing is a localhost interface: 
// -i, --in-interface name: Name of an interface via which a packet was received
# iptables -A INPUT -i lo -j ACCEPT

We tell iptables to add (-A) a rule to the incoming (INPUT) filter table any traffic that comes to localhost interface (-i lo) and to accept (-j ACCEPT) it. Localhost is often used for, ie. your website or email server communicating with a database locally installed. That way our VPS can use the database, but the database is closed to exploits from the internet. 

Now we can allow web server traffic: 
# iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
# iptables -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
# iptables --list
...
ACCEPT tcp -- anywhere anywhere tcp dpt:http
ACCEPT tcp -- anywhere anywhere tcp dpt:https

We added the two ports (http port 80, and https port 443) to the ACCEPT chain - allowing traffic in on those ports. Now, let's allow users use our SMTP servers: 
# iptables -A INPUT -p tcp -m tcp --dport 25 -j ACCEPT
# iptables -A INPUT -p tcp -m tcp --dport 465 -j ACCEPT
# iptables --list
...
ACCEPT tcp -- anywhere anywhere tcp dpt:smtp
ACCEPT tcp -- anywhere anywhere tcp dpt:urd

Like stated before, if we can influence our users, we should rather use the secure version, but often we can't dictate the terms and the clients will connect using port 25, which is much more easier to have passwords sniffed from. We now proceed to allow the users read email on their server: 
# iptables -A INPUT -p tcp -m tcp --dport 110 -j ACCEPT
# iptables -A INPUT -p tcp -m tcp --dport 995 -j ACCEPT
# iptables --list
...
ACCEPT tcp -- anywhere anywhere tcp dpt:pop3
ACCEPT tcp -- anywhere anywhere tcp dpt:pop3s

Those two rules will allow POP3 traffic. Again, we could increase security of our email server by just using the secure version of the service. Now we also need to allow IMAP mail protocol: 
# iptables -A INPUT -p tcp -m tcp --dport 143 -j ACCEPT
# iptables -A INPUT -p tcp -m tcp --dport 993 -j ACCEPT
# iptables --list
...
ACCEPT tcp -- anywhere anywhere tcp dpt:imap
ACCEPT tcp -- anywhere anywhere tcp dpt:imaps

Limiting SSH access 
We should also allow SSH traffic, so we can connect to the VPS remotely. The simple way to do it would be with this command: 
# iptables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
# iptables --list
...
ACCEPT tcp -- anywhere anywhere tcp dpt:ssh

We now told iptables to add a rule for accepting tcp traffic incomming to port 22 (the default SSH port). It is advised to change the SSH configuration to a different port, and this firewall filter should be changed accordingly, but configuring SSH is not a part of this article. However, we could do one more thing about that with firewall itself. If our office has a permanent IP address, we could only allow connections to SSH from this source. This would allow only people from our location to connect. 

First, find out your outside IP address. Make sure it is not an address from your LAN, or it will not work. You could do that simply by visiting the whatismyip.com site. Another way to find it out is to type: 


in the terminal, we should see us logged in (if we're the only one logged in' and our IP address written down). Now, you can create the firewall rule to only allow traffic to SSH port if it comes from one source: your IP address: 
// -s, --source address[/mask][,...]: Source specification. Address can be either a network name, a hostname, a network IP address (with /mask), or a plain IP address.
# iptables -A INPUT -p tcp -s YOUR_IP_ADDRESS -m tcp --dport 22 -j ACCEPT

Replace YOUR_IP_ADDRESS with the actuall IP, of course. 

We could open more ports on our firewall as needed by changing the port numbers. That way our firewall will allow access only to services we want. Right now, we need to add one more rule that will allow us to use outgoing connections (ie. ping from VPS or run software updates); 
// -I, --insert chain [rulenumrule-specification: Insert one or more rules in the selected chain as the given rule number.
# iptables -I INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# iptables --list
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
...

It will allow any established outgoing connections to receive replies from the VPS on the other side of that connection. When we have it all set up, we will block everything else, and allow all outgoing connections. 
// -P, --policy chain target: Set the policy for the chain to the given target.
# iptables -P OUTPUT ACCEPT
# iptables -P INPUT DROP

Now we have our firewall rules in place. 

Save the configuration 
Now that we have all the configuration in, we can list the rules to see if anything is missing. 
// -n, --numeric: Numeric output. IP addresses and port numbers will be printed in numeric format.
// -L, --list [chain]: List all rules in the selected chain.
# iptables -L -n

The -n switch here is because we need only ip addresses, not domain names. Ie. if there is an IP in the rules like this: 69.55.48.33: the firewall would go look it up and see that it was a digitalocean.com IP. We don't need that, just the address itself. Now we can finally save our firewall configuration: 
# iptables-save | sudo tee /etc/sysconfig/iptables

The iptables configuration file on CentOS is located at /etc/sysconfig/iptables. The above command saved the rules we created into that file. Just to make sure everything works, we can restart the firewall: 
# service iptables restart

The saved rules will persist even when the VPS is rebooted. 

Flush to unlock yourself 
If we made an accident in our configuration, we may have blocked ourselves from accessing the VPS. Perhaps we have put in the incorrect IP address so the firewall does not allow connections from our workstation. Now we can't reach those rules, and if we saved them, even a restart won't help us. Luckily, the DO web interface allowes us to connect to server via console: 


Once connected, we log in as root and issue the following command: 
# iptables -F

This will flush the filters, we'll be able to get in the VPS again. 

Conclusion 
This article is not exhaustive, and it only scratched the surface of running a simple firewall on a linux machine. It will do enough for a typical web and email server scenario for a developer not familiar with linux command line or iptables. However, a lot more could be done. There are good tutorials and samples on the internet to help us provide more robust configuration. For production environments, it would be advised to create a more detailed configuration or to have a security expert prepare the configuration.

2016年10月23日 星期日

[Linux 常見問題] How can i use iptables on Centos7?

Source From Here
Question
I installed CentOS 7 with minimal configuration (os + dev tools). I am trying to open 80 port for httpd service, but something wrong with my iptables service:
# ifconfig/sbin/service iptables save
bash: ifconfig/sbin/service: No such file or directory

# /sbin/service iptables save
The service command supports only basic LSB actions (start, stop, restart, try-restart, reload, force-reload, status). For other actions, please try to use systemctl.

# sudo service iptables status
Redirecting to /bin/systemctl status iptables.service
iptables.service
Loaded: not-found
 (Reason: No such file or directory)
Active: inactive (dead)

How-To
With RHEL 7 / CentOS 7, firewalld was introduced to manage iptables. IMHO, firewalld is more suited for workstations than for server environments. It is possible to go back to a more classic iptables setup. First, stop and mask the firewalld service:
# systemctl stop firewalld
# systemctl mask firewalld // Mask one or more unit files, as specified on the command line. This will link these units to /dev/null, making it impossible to start them.

Then, install the iptables-services package:
# yum install iptables-services

Enable the service at boot-time:
# systemctl enable iptables

Managing the service:
# systemctl [stop|start|restart] iptables

Saving your firewall rules can be done as follows:
# service iptables save
or
# /usr/libexec/iptables/iptables.init save


2016年10月22日 星期六

[ Algorithm ] Heap's algorithm for Permutation

Source From Here 
Preface 
Heap's algorithm generates all possible permutations of N objects. It was first proposed by B. R. Heap in 1963.[1] The algorithm minimizes movement: it generates each permutation from the previous one by interchanging a single pair of elements; the other N−2 elements are not disturbed. In a 1977 review of permutation-generating algorithms, Robert Sedgewick concluded that it was at that time the most effective algorithm for generating permutations by computer. 

Details of the algorithm 
Suppose we have a permutation containing N different elements. Heap found a systematic method for choosing at each step a pair of elements to switch, in order to produce every possible permutation of these elements exactly once. Let us describe Heap's method in a recursive way. First we set a counter i to 0. Now we perform the following steps repeatedly until i is equal to N. We use the algorithm to generate the (N − 1)! permutations of the first N − 1 elements, adjoining the last element to each of these. This generates all of the permutations that end with the last element. Then if N is odd, we switch the first element and the last one, while if N is even we can switch the i th element and the last one (there is no difference between N even and odd in the first iteration). We add one to the counter i and repeat. In each iteration, the algorithm will produce all of the permutations that end with the element that has just been moved to the "last" position. The following pseudocode outputs all permutations of a data array of length N
- Recursive Pseudo Code 
  1. procedure generate(n : integer, A : array of any):  
  2.     if n = 1 then  
  3.           output(A)  
  4.     else  
  5.         i := 0  
  6.         while True do  
  7.             generate(n - 1, A)  
  8.             if i = (n - 1) then  
  9.                 break  
  10.             end if  
  11.             if n is even then  
  12.                 swap(A[i], A[n-1])  
  13.             else  
  14.                 swap(A[0], A[n-1])  
  15.             end if  
  16.             i := i + 1  
  17.         end while  
  18.     end if  
One can also write the algorithm in a non-recursive format. 
  1. procedure generate(n : integer, A : array of any):  
  2.     c : array of int  
  3.   
  4.     for i := 0; i < n; i += 1 do  
  5.         c[i] := 0  
  6.     end for  
  7.   
  8.     output(A)  
  9.     i := 1  
  10.     while i < n do  
  11.         if c[i] < i then  
  12.             if i is even then  
  13.                 swap(A[0], A[i])  
  14.             else  
  15.                 swap(A[c[i]], A[i])  
  16.             end if  
  17.             output(A)  
  18.             c[i] += 1  
  19.             i := 1  
  20.         else  
  21.             c[i] := 0  
  22.             i += 1  
  23.         end if  
  24.     end while  
- Java Implementation 
  1. package medium;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.   
  6. public class permutations {  
  7.     /** 
  8.      * Given a collection of distinct numbers, return all possible permutations. 
  9.      * For example, 
  10.      * [1,2,3] have the following permutations: 
  11.      *  
  12.      * [[1,2,3], 
  13.      * [1,3,2], 
  14.      * [2,1,3], 
  15.      * [2,3,1], 
  16.      * [3,1,2], 
  17.      * [3,2,1]] 
  18.      *  
  19.      * @see 
  20.      *  https://en.wikipedia.org/wiki/Heap%27s_algorithm 
  21.      *  
  22.      * @param nums 
  23.      *  Numbers with distinct values to do permutation 
  24.      *  
  25.      * @return 
  26.      */  
  27.     public static List> permute(int[] nums) {  
  28.         List> permList = new ArrayList>();  
  29.           
  30.         generate(nums.length, nums, permList);  
  31.           
  32.         return permList;  
  33.     }  
  34.       
  35.     public static void generate(int n, int[] nums, List> permList)  
  36.     {  
  37.         if(n==1)  
  38.         {  
  39.             List list = new ArrayList();  
  40.             for(int v:nums) list.add(v);  
  41.             permList.add(list);  
  42.         }  
  43.         else  
  44.         {  
  45.             int i = 0;  
  46.             while(true)  
  47.             {  
  48.                 generate(n-1, nums, permList);  
  49.                 if(i==(n-1)) break;  
  50.                 if(n%2==0// even  
  51.                 {  
  52.                     swap(nums, i, n-1);  
  53.                 }  
  54.                 else  
  55.                 {  
  56.                     swap(nums, 0, n-1);  
  57.                 }  
  58.                 i++;  
  59.             }  
  60.         }  
  61.     }  
  62.       
  63.     public static void swap(int[] nums, int i, int j)  
  64.     {  
  65.         int t = nums[i]; nums[i]=nums[j]; nums[j]=t;  
  66.     }  
  67. }  

Supplement 
leetcode - Permutation

[Linux 常見問題] What's the best way to send a signal to all members of a process group?

Source From  Here   Question   I want to  kill a whole process tree.  What is the best way to do this using any common scripting languages? ...