I was setting up data guard environment on Centos 7 machine for testing purposes. Usually I disable iptables firewall at first, but this time firewall stays on and I'll make all necessary holes into it.
TOC
- Overview
- Communication between guests
- Network separation
- Define firewalld service for oracle database
- Communication from host to guests
- Define firewalld service for oracle database console
My environment consists of 2 hosts - centos-dg1 and centos-dg2. Each host have two network cards. Eth0 will be used for client connections. Eth1 will be used for dataguard
communication. Eth0 cards are plugged to network 192.168.122.0/8 and eth1 cards to 192.168.254.0/8. I will name 192.168.122.0/8 network as public network and 192.168.254.0/8 as
internal network.
Primary database is named PROD
and standby is STPROD
.There are 2 listeners on each machine. LISTENER_LOCAL
is used for client
connections. It is bound to public network. LISTENER_DG
is used for Data Guard communication and is bound to internal network.
This is how I image communication through firewall:
- Client connection (e.g. sqlplus) from host to both guests via Oracle Net (TCP:1521)
- Connection from host to database control on primary database (TCP:1158)
- Data Guard connections between guests (TCP:1521)
Communication between guests
At first I'll check if it is by any chance working out of the box. I've started listeners on the first guest, the are bound to correct addresses and ports:
[oracle@centos-dg1 PROD ~]$ sudo netstat -tnlp | grep 1521 tcp 0 0 192.168.254.10:1521 0.0.0.0:* LISTEN 3234/tnslsnr tcp 0 0 192.168.122.175:1521 0.0.0.0:* LISTEN 3229/tnslsnr
First line belongs to the LISTENER_LOCAL
and second to the LISTENER_DG
. I'll try to tnsping both listeners from first guest:
[oracle@centos-dg1 PROD ~]$ tnsping LISTENER_LOCAL . . . Attempting to contact (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = centos-dg1.localdomain)(PORT = 1521)(IP = FIRST))) OK (0 msec) [oracle@centos-dg1 PROD ~]$ tnsping LISTENER_DG . . . Used TNSNAMES adapter to resolve the alias Attempting to contact (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = centos-dg1-dg.localdomain)(PORT = 1521)(IP = FIRST))) OK (0 msec)
Working. But it is no surprise because I'm connecting to the same machine where I'm logged in. This kind of communication is usually allowed. I'll try it from other guest:
[oracle@centos-dg2 STPROD ~]$ tnsping PROD . . . Attempting to contact (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = centos-dg1.localdomain)(PORT = 1521)) (CONNECT_DATA = (SERVICE_NAME = PROD.LOCALDOMAIN))) TNS-12543: TNS:destination host unreachable [oracle@centos-dg2 STPROD ~]$ tnsping PROD_DG . . . Attempting to contact (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = centos-dg1-dg.localdomain)(PORT = 1521)) (CONNECT_DATA = (SERVICE_NAME = PROD.LOCALDOMAIN))) TNS-12543: TNS:destination host unreachable
Error message means that communication is not allowed to pass through the firewall.
Network separation
I will look at zones. I can see only one active zone:
[root@centos-dg1 ~]# firewall-cmd --get-active-zones public interfaces: eth0 eth1
Public zone contains both interfaces which I don't like. I want to create internal zone with eth1 interface. Here it comes:
[root@centos-dg1 ~]# firewall-cmd --get-active-zones public interfaces: eth0 eth1 [root@centos-dg1 ~]# firewall-cmd --zone=public --remove-interface=eth1 success [root@centos-dg1 ~]# firewall-cmd --zone=public --remove-interface=eth1 --permanent success [root@centos-dg1 ~]# firewall-cmd --zone=internal --add-interface=eth1 success [root@centos-dg1 ~]# firewall-cmd --zone=internal --add-interface=eth1 --permanent success [root@centos-dg1 ~]# firewall-cmd --get-active-zones internal interfaces: eth1 public interfaces: eth0
Now I have two zones as I like it - public network interface in public zone and internal network interface in internal zone.
Define firewalld service for oracle database
I need to tell firewalld that it should kindly allow communication to TCP:1521 between guest machines. I'll define firewalld services:
[root@centos-dg1 ~]# cat /tmp/oracledb.xml <?xml version="1.0" encoding="utf-8"?> <service> <short>OracleDB</short> <description>Service for connection to Oracle database. If you plan to provide a database connection on this host, enable this option.</description> <port protocol="tcp" port="1521"/> </service>
I'll move this file to /etc/firewalld/services
where all user defined services belongs. I'll not forget to set correct privileges and selinux context:
[root@centos-dg1 ~]# mv /tmp/oracledb.xml /etc/firewalld/services/ [root@centos-dg1 ~]# ls -lZ /etc/firewalld/services/oracledb.xml -rw-r--r--. root root system_u:object_r:firewalld_etc_rw_t:s0 /etc/firewalld/services/oracledb.xml
After reloading firewalld I can see oracledb among services:
[root@centos-dg1 ~]# systemctl reload firewalld.service [root@centos-dg1 ~]# firewall-cmd --get-services amanda-client bacula bacula-client dhcp dhcpv6 dhcpv6-client dns ftp high-availability http https imaps ipp ipp-client ipsec kerberos kpasswd ldap ldaps libvirt libvirt-tls mdns mountd ms-wbt mysql nfs ntp openvpn oracledb pmcd pmproxy pmwebapi pmwebapis pop3s postgresql proxy-dhcp radius rpc-bind samba samba-client smtp ssh telnet tftp tftp-client transmission-client vnc-server wbem-https
I'll print which services are allowed in internal zone.
[root@centos-dg1 ~]# firewall-cmd --list-services --zone=internal dhcpv6-client ipp-client mdns samba-client ssh
No oracledb service there! I have to add service oracledb to internal zone:
[root@centos-dg1 ~]# firewall-cmd --list-services --zone=internal dhcpv6-client ipp-client mdns samba-client ssh [root@centos-dg1 ~]# firewall-cmd --add-service=oracledb --zone=internal success [root@centos-dg1 ~]# firewall-cmd --add-service=oracledb --zone=internal --permanent success [root@centos-dg1 ~]# firewall-cmd --list-services --zone=internal dhcpv6-client ipp-client mdns oracledb samba-client ssh
Connection from second guest to the first guest's internal network (guest2 -> guest1:internal network:1521) should work now:
[oracle@centos-dg2 STPROD ~]$ tnsping PROD_DG . . . Attempting to contact (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = centos-dg1-dg.localdomain)(PORT = 1521)) (CONNECT_DATA = (SERVICE_NAME = PROD.LOCALDOMAIN))) OK (10 msec)
I will run same commands on the other guest in order to achieve same goal (guest1 -> guest2:internal network:1521):
[root@centos-dg2 ~]# scp centos-dg1:/etc/firewalld/services/oracledb.xml /etc/firewalld/services/ oracledb.xml 100% 274 0.3KB/s 00:00 [root@centos-dg2 ~]# chcon -u system_u /etc/firewalld/services/oracledb.xml [root@centos-dg2 ~]# systemctl reload firewalld.service [root@centos-dg2 ~]# firewall-cmd --zone=public --remove-interface=eth1 success [root@centos-dg2 ~]# firewall-cmd --zone=public --remove-interface=eth1 --permanent success [root@centos-dg2 ~]# firewall-cmd --zone=internal --add-interface=eth1 success [root@centos-dg2 ~]# firewall-cmd --zone=internal --add-interface=eth1 --permanent success [root@centos-dg2 ~]# firewall-cmd --add-service=oracledb --zone=internal success [root@centos-dg2 ~]# firewall-cmd --add-service=oracledb --zone=internal --permanent success [root@centos-dg2 ~]# firewall-cmd --list-services --zone=internal dhcpv6-client ipp-client mdns oracledb samba-client ssh
I'll check Oracle Net connection from this direction:
[root@centos-dg1 ~]# tnsping STPROD_DG . . . Attempting to contact (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = centos-dg2-dg.localdomain)(PORT = 1521)) (CONNECT_DATA = (SERVICE_NAME = STPROD.LOCALDOMAIN))) OK (10 msec)
Communication from host to guests
I want to log into databases from host. I'll check whether communication is allowed or not:
[vajko@kra ~]$ tnsping PROD . . . Attempting to contact (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = centos-dg1.localdomain)(PORT = 1521)) (CONNECT_DATA = (SERVICE_NAME = PROD.LOCALDOMAIN))) TNS-12543: TNS:destination host unreachable [vajko@kra ~]$ tnsping STPROD . . . Attempting to contact (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = centos-dg2.localdomain)(PORT = 1521)) (CONNECT_DATA = (SERVICE_NAME = STPROD.LOCALDOMAIN))) TNS-12543: TNS:destination host unreachable
Communication is denied by firewall again. Adding oracledb service to public zone on both guests will solve the problem:
[root@centos-dg1 ~]# firewall-cmd --add-service=oracledb --zone=public success [root@centos-dg1 ~]# firewall-cmd --add-service=oracledb --zone=public --permanent success [root@centos-dg2 ~]# firewall-cmd --add-service=oracledb --zone=public success [root@centos-dg2 ~]# firewall-cmd --add-service=oracledb --zone=public --permanent success
And check:
[vajko@kra ~]$ tnsping PROD . . . Attempting to contact (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = centos-dg1.localdomain)(PORT = 1521)) (CONNECT_DATA = (SERVICE_NAME = PROD.LOCALDOMAIN))) OK (0 msec) [vajko@kra ~]$ tnsping STPROD . . . Attempting to contact (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = centos-dg2.localdomain)(PORT = 1521)) (CONNECT_DATA = (SERVICE_NAME = STPROD.LOCALDOMAIN))) OK (0 msec)
Working as advertised. Last thing which needs to be checked is database console.
Define firewalld service for oracle database console
I'll start database console and check to which interface it is bound:
[oracle@centos-dg1 PROD ~]$ emctl start dbconsole Oracle Enterprise Manager 11g Database Control Release 11.2.0.3.0 Copyright (c) 1996, 2011 Oracle Corporation. All rights reserved. http://centos-dg1:1158/em/console/aboutApplication Starting Oracle Enterprise Manager 11g Database Control .... started. ------------------------------------------------------------------ Logs are generated in directory /u01/app/oracle/product/11.2.0/db_1/centos-dg1_PROD/sysman/log [oracle@centos-dg1 PROD ~]$ netstat -tnlp | grep 1158 (Not all processes could be identified, non-owned process info will not be shown, you would have to be root to see it all.) tcp6 1 0 :::1158 :::* LISTEN 3553/java
Database console is running and bound to all interfaces which I don't mind. I'll try to connect from host:
[vajko@kra ~]$ telnet centos-dg1 1158 Trying 192.168.122.175... telnet: connect to address 192.168.122.175: No route to host
It is denied as expected. Therefore I will define firewalld service for database console:
[root@centos-dg1 ~]# cat /tmp/oracledbconsole.xml <?xml version="1.0" encoding="utf-8"?> <service> <short>Oracle database console</short> <description>Bla bla bla oracle db console bla bla bla</description> <port protocol="tcp" port="1158"/> </service>
I'll move it to correct location and reload firewalld:
[root@centos-dg1 ~]# mv /tmp/oracledbconsole.xml /etc/firewalld/services/ [root@centos-dg1 ~]# ls -lZ /etc/firewalld/services/oracledbconsole.xml -rw-r--r--. root root system_u:object_r:firewalld_etc_rw_t:s0 /etc/firewalld/services/oracledbconsole.xml [root@centos-dg1 ~]# systemctl reload firewalld.service
I'll add oracledbconsole service to public zone:
[root@centos-dg1 ~]# firewall-cmd --add-service=oracledbconsole --zone=public success [root@centos-dg1 ~]# firewall-cmd --add-service=oracledbconsole --zone=public --permanent success
Now I can finally connect to database console from host:
[vajko@kra ~]$ telnet centos-dg1 1158 Trying 192.168.122.175... Connected to centos-dg1. Escape character is '^]'.
How to enable communication to database console on second guest (in case of switchover or failover)? I will kindly leave it as excercise to reader.
No comments:
Post a Comment