Apache Derby数据库JVM安全策略
抽象
我已經(jīng)發(fā)布了許多有關(guān)Derby的博客:
- Derby數(shù)據(jù)庫(kù)備份
- 同一主機(jī)上的多個(gè)Derby網(wǎng)絡(luò)服務(wù)器
- Apache Derby數(shù)據(jù)庫(kù)用戶和權(quán)限
- 與Maven和內(nèi)存中Derby數(shù)據(jù)庫(kù)的集成測(cè)試
這本不打算是一個(gè)系列。 但是多年來(lái),我越來(lái)越多地使用Derby。 我開(kāi)始使用Derby作為微服務(wù)體系結(jié)構(gòu)的首選數(shù)據(jù)庫(kù)。 這些是個(gè)人使用的應(yīng)用程序,因此Derby綽綽有余。 即使這些是個(gè)人使用的應(yīng)用程序,我也需要具有有限用戶權(quán)限的 多臺(tái)服務(wù)器 ,當(dāng)然還有數(shù)據(jù)庫(kù)備份和還原 。 最終要求是安全性。 我使用derby usr帳戶在Ubuntu Linux VM上運(yùn)行Derby數(shù)據(jù)庫(kù)。 盡管derby usr帳戶對(duì)VM的權(quán)限有限,但是任何額外的安全層都是好的。 因此,本博客的目的是演示如何使用Java安全策略運(yùn)行Derby,以限制JVM的權(quán)限并增強(qiáng)運(yùn)行時(shí)安全性。
免責(zé)聲明
這篇文章僅供參考。 在使用所提供的任何信息之前,請(qǐng)認(rèn)真思考。 從中學(xué)到東西,但最終自己做出決定,風(fēng)險(xiǎn)自負(fù)。
要求
我使用以下主要技術(shù)完成了本文的所有工作。 您可能可以使用不同的技術(shù)或版本來(lái)做相同的事情,但不能保證。
- Apache Derby 10.14.2.0
- Java zulu11.39.15-ca-jdk11.0.7-linux_x64
我將不涉及下載和安裝這些技術(shù)的過(guò)程。 我將其留給您練習(xí)。
注意從版本10.15開(kāi)始,Derby項(xiàng)目已更新為使用Java 9模塊系統(tǒng)。 結(jié)果,JAR文件已經(jīng)發(fā)生了很大變化。 下面的security.policy不太可能與10.15+版本一起使用。 截至本博客的發(fā)布日期,我還沒(méi)有嘗試過(guò)。
Linux bash腳本
為了管理Derby使其與Java安全策略一起運(yùn)行,您需要3個(gè)腳本。 第一個(gè)腳本將設(shè)置設(shè)置環(huán)境變量以配置Derby。 第二個(gè)腳本將啟動(dòng)Derby網(wǎng)絡(luò)服務(wù)器,并傳遞正確的命令行參數(shù)。 第三臺(tái)將停止Derby網(wǎng)絡(luò)服務(wù)器。
清單1.1向您展示了這些腳本中的第一個(gè)。 它導(dǎo)出具有特定配置值的許多系統(tǒng)環(huán)境變量,這些配置值專門用于在您的環(huán)境中運(yùn)行Derby。
清單1.1 – setenv.sh
#!/bin/bash export DERBY_HOME=/home/derby/opt/derby export PATH= "$DERBY_HOME/bin:$PATH" echo "DERBY_HOME=$DERBY_HOME" export JAVA_HOME=/home/derby/opt/java echo "JAVA_HOME=$JAVA_HOME" export NS_HOME=/var/local/derby/ 1527 mkdir -p $NS_HOME echo "NS_HOME=$NS_HOME" export NS_PORT= 1527 echo "NS_PORT=$NS_PORT" export NS_HOST= 0.0 . 0.0 echo "NS_HOST=$NS_HOST" export DERBY_OPTS= "" export DERBY_OPTS= "$DERBY_OPTS -Dderby.drda.host=$NS_HOST" export DERBY_OPTS= "$DERBY_OPTS -Dderby.drda.portNumber=$NS_PORT" export DERBY_OPTS= "$DERBY_OPTS -Dderby.system.home=$NS_HOME" # Security Policy export DERBY_OPTS= "$DERBY_OPTS -Dderby.stream.error.logSeverityLevel=0" export DERBY_OPTS= "$DERBY_OPTS -Dderby.security.port=$NS_PORT" export DERBY_OPTS= "$DERBY_OPTS -Dderby.install.url=file:$DERBY_HOME/lib/" export DERBY_OPTS= "$DERBY_OPTS -Djava.security.manager" export DERBY_OPTS= "$DERBY_OPTS -Djava.security.policy=$NS_HOME/security.policy"DERBY_HOME不言自明。 這是解壓縮(安裝)Derby的地方。 將Derby的bin目錄添加到PATH 。
JAVA_HOME是不言自明的。 這是解壓縮(安裝)Java的地方。 將Java的bin目錄添加到PATH 。
NS_HOME是“N etwork 小號(hào) erver家”。 這是Derby網(wǎng)絡(luò)服務(wù)器將用于存儲(chǔ)其配置和數(shù)據(jù)庫(kù)的目錄。 每當(dāng)在此Derby網(wǎng)絡(luò)服務(wù)器上創(chuàng)建新數(shù)據(jù)庫(kù)時(shí),都會(huì)在NS_HOME下為新數(shù)據(jù)庫(kù)創(chuàng)建一個(gè)新的子目錄。 這允許在同一主機(jī)上運(yùn)行的多個(gè)Derby網(wǎng)絡(luò)服務(wù)器將其數(shù)據(jù)分開(kāi)。
NS_PORT是“N etwork 小號(hào) erver端口”。 這是Derby網(wǎng)絡(luò)服務(wù)器用來(lái)偵聽(tīng)連接的端口。 這允許多個(gè)Derby網(wǎng)絡(luò)服務(wù)器在同一主機(jī)上運(yùn)行。
NS_HOST是“N etwork 小號(hào) erver主機(jī)”。 它設(shè)置偵聽(tīng)連接時(shí)Derby網(wǎng)絡(luò)服務(wù)器使用的網(wǎng)絡(luò)接口。 默認(rèn)情況下,Derby網(wǎng)絡(luò)服務(wù)器僅在127.0.0.1的環(huán)回地址上偵聽(tīng)連接。 此默認(rèn)值表示客戶端必須與網(wǎng)絡(luò)服務(wù)器在同一主機(jī)上運(yùn)行-不太有用。 通過(guò)將主機(jī)設(shè)置為0.0.0.0 ,Derby網(wǎng)絡(luò)服務(wù)器將偵聽(tīng)主機(jī)上任何網(wǎng)絡(luò)接口上的連接。 如果您的VM具有多個(gè)網(wǎng)絡(luò)接口,則應(yīng)將NS_HOST設(shè)置為這些接口之一的IP。 設(shè)置此值可使客戶端成為遠(yuǎn)程客戶端。
DERBY_OPTS是用于將所有配置選項(xiàng)獲取到Derby的系統(tǒng)屬性。 通過(guò)將適當(dāng)?shù)腄erby系統(tǒng)屬性及其關(guān)聯(lián)值連接在一起來(lái)創(chuàng)建其值。 使用或不使用安全策略來(lái)啟動(dòng)Derby都需要前三個(gè)屬性。
配置Derby使其與安全策略一起運(yùn)行時(shí),需要最后5個(gè)屬性。
其中最重要的特性之一是java.security.policy=$NS_HOME/security.policy" 。這個(gè)屬性指向的值security.policy文件,該文件將配置Java SecurityManager ,你會(huì)讀到有關(guān)創(chuàng)建security.policy文件接下來(lái),您將看一下啟動(dòng)服務(wù)器的腳本。
清單1.2顯示了這些腳本的第二個(gè)。 它會(huì)啟動(dòng)Derby網(wǎng)絡(luò)服務(wù)器,并傳遞正確的命令行參數(shù),因此Derby會(huì)以安全策略運(yùn)行。
清單1.2 – start.sh
#!/bin/bash # Directory of the script SD=$( cd "$( dirname " ${BASH_SOURCE[ 0 ]} " )" && pwd ) # Source in common variables source $SD/setenv.sh # Symlink the network server configurations ln -sf $SD/../conf/security.policy $NS_HOME/security.policy ln -sf $SD/../conf/derby.properties $NS_HOME/derby.properties startNetworkServerSD是S CRIPT d irectory。 該評(píng)估確定start.sh腳本的標(biāo)準(zhǔn)文件系統(tǒng)位置,并將其分配給SD 。 當(dāng)引用其他腳本時(shí),這很有用。
來(lái)源不言自明。 它在系統(tǒng)環(huán)境變量中來(lái)源以配置Derby網(wǎng)絡(luò)服務(wù)器。 有關(guān)詳細(xì)信息,請(qǐng)參見(jiàn)清單1.1。
Symlink配置適用于security.policy文件和derby.properties文件。 符號(hào)鏈接的目的是將這兩個(gè)文件放入$NS_HOME目錄。 Derby在$NS_HOME目錄中尋找derby.properties文件,因此它必須存在。 為了保持一致性(不是必需的),您還希望將security.policy文件放在此處。 在清單1.1中, java.security.policy=$NS_HOME/security.policy"屬性配置了此位置。對(duì)于我的環(huán)境,我將$NS_HOME目錄與保存管理腳本和其他Derby配置文件的目錄分開(kāi)。我這樣做是因?yàn)闉?zāi)難恢復(fù),我認(rèn)為$NS_HOME目錄是$NS_HOME ,這意味著如果由于某種原因它丟失了(刪除,磁盤驅(qū)動(dòng)器錯(cuò)誤,損壞,構(gòu)建新的VM等),我必須能夠恢復(fù)數(shù)據(jù)庫(kù)數(shù)據(jù),管理腳本( setenv.sh , start.sh , stop.sh )和配置文件( security.policy , derby.properties從我的云備份)。 真正的配置文件的保留之外$NS_HOME目錄, start.sh將它們?cè)谡_的位置符號(hào)鏈接。
startNetworkServer是Derby提供的腳本( $DERBY_HOME/bin ),用于啟動(dòng)網(wǎng)絡(luò)服務(wù)器。 該DERBY_OPTS變量-在設(shè)置setenv.sh -用于配置網(wǎng)絡(luò)服務(wù)器。 默認(rèn)情況下,Derby使用有限的安全策略運(yùn)行。 但是,由于配置了安全策略,因此Derby將使用您的配置而不是默認(rèn)配置。
現(xiàn)在,您具有Derby服務(wù)器環(huán)境配置和啟動(dòng)腳本。 您還沒(méi)有能夠停止Derby網(wǎng)絡(luò)服務(wù)器的功能。 停止服務(wù)器很容易。 您將查看下一個(gè)用于停止服務(wù)器的腳本。
注意仍然還需要security.policy文件。 我保證,您將在短時(shí)間內(nèi)閱讀到有關(guān)它的信息!
清單1.3顯示了這些腳本的第三個(gè)。 它將停止Derby網(wǎng)絡(luò)服務(wù)器。 不太令人興奮,但是對(duì)服務(wù)器進(jìn)行有管理的關(guān)閉以防止數(shù)據(jù)損壞很重要。
清單1.3 – stop.sh
#!/bin/bash # Directory of the script SD=$( cd "$( dirname " ${BASH_SOURCE[ 0 ]} " )" && pwd ) # Source in common variables source $SD/setenv.sh stopNetworkServer所有這些都是不言自明的。 此腳本不需要進(jìn)一步的注釋。
security.policy文件
Derby隨附一個(gè)演示安全策略文件。 它位于DERBY_HOME/demo/templates/security.policy 。 使用此文件作為起點(diǎn),我能夠生成滿足以下要求的最終版本:
- 網(wǎng)絡(luò)(遠(yuǎn)程)訪問(wèn)
- 本地主機(jī)訪問(wèn)
- 啟動(dòng)
- 關(guān)掉
- 后備
清單2.1 – security.policy
// // Licensed to the Apache Software Foundation (ASF) under one or more // contributor license agreements. See the NOTICE file distributed with // this work for additional information regarding copyright ownership. // The ASF licenses this file to You under the Apache License, Version 2.0 // (the "License"); you may not use this file except in compliance with // the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // grant codeBase "${derby.install.url}derby.jar" { // These permissions are needed for everyday, embedded Derby usage. // permission java.lang.RuntimePermission "createClassLoader" ; permission java.util.PropertyPermission "derby.*" , "read" ; permission java.util.PropertyPermission "user.dir" , "read" ; permission org.apache.derby.security.SystemPermission "engine" , "usederbyinternals" ; // The next two properties are used to determine if the VM is 32 or 64 bit. // permission java.util.PropertyPermission "sun.arch.data.model" , "read" ; permission java.util.PropertyPermission "os.arch" , "read" ; permission java.io.FilePermission "${derby.system.home}" , "read" ; permission java.io.FilePermission "${derby.system.home}${/}-" , "read,write,delete" ; // Needed by sysinfo. A file permission is needed to check the existence of // jars on the classpath. You can limit this permission to just the locations // which hold your jar files. This block is reproduced for all codebases // which include the sysinfo classes--the policy file syntax does not let you // grant permissions to several codebases all at once. // permission java.util.PropertyPermission "user.*" , "read" ; permission java.util.PropertyPermission "java.home" , "read" ; permission java.util.PropertyPermission "java.class.path" , "read" ; permission java.util.PropertyPermission "java.runtime.version" , "read" ; permission java.util.PropertyPermission "java.fullversion" , "read" ; permission java.lang.RuntimePermission "getProtectionDomain" ; permission java.io.FilePermission "java.runtime.version" , "read" ; permission java.io.FilePermission "java.fullversion" , "read" ; permission java.io.FilePermission "${derby.install.path}${/}-" , "read" ; permission java.io.FilePermission "/tmp${/}-" , "read,write,delete" ; // Permissions needed for JMX based management and monitoring. // // Allows this code to create an MBeanServer: // permission javax.management.MBeanServerPermission "createMBeanServer" ; // Allows access to Derby's built-in MBeans, within the domain // org.apache.derby. Derby must be allowed to register and unregister these // MBeans. To fine tune this permission, see the javadoc of // javax.management.MBeanPermission or the JMX Instrumentation and Agent // Specification. // permission javax.management.MBeanPermission "org.apache.derby.*#[org.apache.derby:*]" , "registerMBean,unregisterMBean" ; // Trusts Derby code to be a source of MBeans and to register these in the // MBean server. // permission javax.management.MBeanTrustPermission "register" ; // Gives permission for jmx to be used against Derby but only if JMX // authentication is not being used. In that case the application would need // to create a whole set of fine-grained permissions to allow specific users // access to MBeans and actions they perform. // permission org.apache.derby.security.SystemPermission "jmx" , "control" ; permission org.apache.derby.security.SystemPermission "engine" , "monitor" ; permission org.apache.derby.security.SystemPermission "server" , "monitor" ; // getProtectionDomain is an optional permission needed for printing // classpath information to derby.log // permission java.lang.RuntimePermission "getProtectionDomain" ; // The following permission must be granted for Connection.abort(Executor) to // work. Note that this permission must also be granted to outer // (application) code domains. // permission java.sql.SQLPermission "callAbort" ; permission java.sql.SQLPermission "deregisterDriver" ; // Needed by FileUtil#limitAccessToOwner // permission java.lang.RuntimePermission "accessUserInformation" ; permission java.lang.RuntimePermission "getFileStoreAttributes" ; }; grant codeBase "${derby.install.url}derbynet.jar" { // These permissions lets the Network Server manage connections from clients. // Accept connections from any host. Derby is listening to the host interface // specified via the -h option to "NetworkServerControl start" on the command // line, via the address parameter to the // org.apache.derby.drda.NetworkServerControl constructor in the API or via // the property derby.drda.host; the default is localhost. You may want to // restrict allowed hosts, eg to hosts in a specific subdomain, // eg "*.example.com". // permission java.net.SocketPermission "*" , "accept" ; // Allow the server to listen to the socket on the port specified with the // -p option to "NetworkServerControl start" on the command line, or with // the portNumber parameter to the NetworkServerControl constructor in the // API, or with the property derby.drda.portNumber. The default is 1527. permission java.net.SocketPermission "localhost:${derby.security.port}" , "listen" ; permission java.net.SocketPermission "${derby.drda.host}:${derby.security.port}" , "listen" ; // Needed for server tracing. // permission java.io.FilePermission "${derby.drda.traceDirectory}${/}-" , "read,write,delete" ; // Needed by FileUtil#limitAccessToOwner // permission java.lang.RuntimePermission "accessUserInformation" ; permission java.lang.RuntimePermission "getFileStoreAttributes" ; // Needed for NetworkServerMBean access (see JMX section above) // permission org.apache.derby.security.SystemPermission "server" , "control,monitor" ; permission org.apache.derby.security.SystemPermission "engine" , "usederbyinternals" ; // Needed by sysinfo. A file permission is needed to check the existence of // jars on the classpath. You can limit this permission to just the locations // which hold your jar files. This block is reproduced for all codebases // which include the sysinfo classes--the policy file syntax does not let you // grant permissions to several codebases all at once. // permission java.util.PropertyPermission "user.*" , "read" ; permission java.util.PropertyPermission "java.home" , "read" ; permission java.util.PropertyPermission "java.class.path" , "read" ; permission java.util.PropertyPermission "java.runtime.version" , "read" ; permission java.util.PropertyPermission "java.fullversion" , "read" ; permission java.lang.RuntimePermission "getProtectionDomain" ; permission java.io.FilePermission "java.runtime.version" , "read" ; permission java.io.FilePermission "java.fullversion" , "read" ; permission java.io.FilePermission "${derby.install.path}${/}-" , "read" ; permission java.util.PropertyPermission "derby.*" , "read,write" ; permission java.net.SocketPermission "localhost:${derby.security.port}" , "connect,resolve" ; permission java.net.SocketPermission "${derby.drda.host}:${derby.security.port}" , "connect,resolve" ; }; grant codeBase "${derby.install.url}derbytools.jar" { // Needed by sysinfo. A file permission is needed to check the existence of // jars on the classpath. You can limit this permission to just the locations // which hold your jar files. This block is for all codebases which include // the sysinfo classes--the policy file syntax does not let you grant // permissions to several codebases all at once. // permission java.util.PropertyPermission "user.*" , "read" ; permission java.util.PropertyPermission "java.home" , "read" ; permission java.util.PropertyPermission "java.class.path" , "read" ; permission java.util.PropertyPermission "java.runtime.version" , "read" ; permission java.util.PropertyPermission "java.fullversion" , "read" ; permission java.lang.RuntimePermission "getProtectionDomain" ; permission java.io.FilePermission "<<ALL FILES>>" , "read" ; permission java.io.FilePermission "java.runtime.version" , "read" ; permission java.io.FilePermission "java.fullversion" , "read" ; permission java.util.PropertyPermission "*" , "read,write" ; }; grant codeBase "${derby.install.url}derbyclient.jar" { // Needed by sysinfo. A file permission is needed to check the existence of // jars on the classpath. You can limit this permission to just the locations // which hold your jar files. This block is reproduced for all codebases // which include the sysinfo classes--the policy file syntax does not let you // grant permissions to several codebases all at once. // permission java.util.PropertyPermission "user.*" , "read" ; permission java.util.PropertyPermission "java.home" , "read" ; permission java.util.PropertyPermission "java.class.path" , "read" ; permission java.util.PropertyPermission "java.runtime.version" , "read" ; permission java.util.PropertyPermission "java.fullversion" , "read" ; permission java.lang.RuntimePermission "getProtectionDomain" ; permission java.io.FilePermission "${derby.install.path}${/}-" , "read" ; // The following permission must be granted for Connection.abort(Executor) to // work. Note that this permission must also be granted to outer // (application) code domains. // permission java.sql.SQLPermission "callAbort" ; permission java.net.SocketPermission "localhost:${derby.security.port}" , "connect,resolve" ; permission java.net.SocketPermission "${derby.drda.host}:${derby.security.port}" , "connect,resolve" ; };策略文件很多。使用Java 20年后,我只遇到過(guò)幾次。 我不假裝知道策略文件中的所有內(nèi)容。 我所知道的是,此文件可滿足我的所有要求。 每次Derby更新都需要進(jìn)行測(cè)試,并且可能需要進(jìn)行一些調(diào)整。 derby-users@db.apache.org郵件列表是您最好的信息來(lái)源。
從derby-users@db.apache.org郵件列表向Rick Hillegas大聲喊叫,以幫助我獲得此版本的策略文件。 他提供了大部分內(nèi)容,我添加了以下內(nèi)容以滿足我的要求。
第50行permission java.io.FilePermission "/tmp${/}-", "read,write,delete"; 。 我的數(shù)據(jù)庫(kù)備份過(guò)程使用CALL SYSCS_UTIL.SYSCS_BACKUP_DATABASE ('/tmp/resiste-backup/1527') 。 因此, derby.jar文件需要對(duì)文件系統(tǒng)上/tmp目錄的讀取,寫入,刪除權(quán)限,以便可以將備份寫入該目錄。
第92行permission java.sql.SQLPermission "deregisterDriver"; 。 使用ij工具管理我的Derby數(shù)據(jù)庫(kù)時(shí),在derby.log文件中發(fā)現(xiàn)了關(guān)于deregisterDriver的異常。 因此,我也將此權(quán)限添加到了derby.jar文件中。
第160行permission java.net.SocketPermission "${derby.drda.host}:${derby.security.port}", "connect,resolve"; 。 屬性derby.drda.host和derby.security.port在設(shè)定setenv.sh腳本(列表1.1)。 我必須添加此權(quán)限,因?yàn)檫h(yuǎn)程(非本地主機(jī))客戶端可以訪問(wèn)我的Derby網(wǎng)絡(luò)服務(wù)器。 在setenv.sh ,我用-Dderby.drda.host=0.0.0.0覆蓋默認(rèn)的本地主機(jī)唯一接口監(jiān)聽(tīng)。 我還發(fā)現(xiàn)在測(cè)試stop.sh腳本(清單1.3)時(shí),我需要在策略文件中使用stop.sh 。
摘要
而已。 希望您喜歡學(xué)習(xí)如何使用安全策略來(lái)運(yùn)行Derby網(wǎng)絡(luò)服務(wù)器。
翻譯自: https://www.javacodegeeks.com/2020/04/apache-derby-database-jvm-security-policy.html
總結(jié)
以上是生活随笔為你收集整理的Apache Derby数据库JVM安全策略的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 吉卜力工作室被日本电视台收购,宫崎骏长子
- 下一篇: crv安卓手机投屏教程(crv安卓)