Step by Step 實(shí)現(xiàn)基于 Cloudera 5.8.2 的企業(yè)級安全大數(shù)據(jù)平臺 -?傳輸層加密配置 -?Hadoop 組件傳輸層加密

請結(jié)合閱讀Step by Step 實(shí)現(xiàn)基于 Cloudera 5.8.2 的企業(yè)級安全大數(shù)據(jù)平臺 - 傳輸層加密配置 - Clouder Manager 組件傳輸層加密,避免闡述概念模糊和理解偏差。

Hadoop 服務(wù)在 TLS/SSL 加密過程中充當(dāng)?shù)慕巧?/h2>
  • HDFS, YARN 服務(wù)端气忠、客戶端匠楚;
  • HBase 服務(wù)端;
  • Oozie 服務(wù)端僻弹;
  • HUE 是以上所有服務(wù)的客戶端;

服務(wù)端進(jìn)程在啟動(dòng)的時(shí)候會(huì)加載密鑰庫 JKS,當(dāng)客戶端與其通信時(shí)房午,服務(wù)端把證書傳給客戶端,客戶端會(huì)把證書在本地的可信庫進(jìn)行比對丹允,以進(jìn)行認(rèn)證郭厌。

相關(guān)文件,這里的服務(wù)端和客戶端指的是 TLS / SSL 范疇:

  • 服務(wù)端需要:每臺服務(wù)端的證書文件(JKS):${BASE_SECURITY_PATH}/jks/cms.keystore嫌松;
  • 客戶端需要:包含所有主機(jī)證書的可信庫(JKS沪曙,TRUSTSTORE),包含所有服務(wù)端的證書:${JAVA_HOME}/jre/lib/security/jssecacerts.public萎羔;
  • 服務(wù)端或 Cloudera Agent 需要:hue, impala, cloudera-scm-agent 的每臺服務(wù)端的證書文件(PEM)液走,由 JKS 轉(zhuǎn)換而來:${BASE_SECURITY_PATH}/x509/cms.pem.${服務(wù)名} 或者 ${BASE_SECURITY_PATH}/x509/cms.pem.${主機(jī)名}
  • 客戶端需要:hue, impala的客戶端的可信庫文件(PEM),包含所有服務(wù)端的證書缘眶,由 cms.pem 合并而來:${BASE_SECURITY_PATH}/x509/cms.pem.${服務(wù)名}.public嘱根;
  • PEM格式的密碼文件:${BASE_SECURITY_PATH}/x509/agentkey.pw.${主機(jī)名},只用在 Cloudera Agent 的配置文件中巷懈;

在每次配置后需要做基于 HUE 的功能測試:

  • hive editor该抒;
  • impala editor;
  • HBase;
  • Ooize editor;
  • Hive Tables;
  • File ACLs;

證書兼容性

Python 類組件使用 PEM:HUE, Impala;

Java 類組件使用 JKS:HDFS, YARN, Hive, HBase, Oozie顶燕;

配置 HDFS 加密

前序條件和須知:

  • 必須首先集成了 Kerberos凑保;
  • HDFS 的服務(wù)既是 TLS/SSL 的客戶端角色,也是服務(wù)端角色涌攻,因此必須具有對信任公共庫的訪問權(quán)限欧引。做法是把信任庫部署到所有主機(jī)上(這一步在上一篇Step by Step 實(shí)現(xiàn)基于 Cloudera 5.8.2 的企業(yè)級安全大數(shù)據(jù)平臺 - 傳輸層加密配置 - Clouder Manager 組件傳輸層加密中已經(jīng)完成:${JAVA_HOME}/jre/lib/security/jssecacerts.public),而不允許動(dòng)態(tài)把非可信的節(jié)點(diǎn)直接擴(kuò)容恳谎。
  • HDFS 的密鑰必須由 hadoop 組所有芝此,440權(quán)限;
  • 信任庫必須有 444 權(quán)限因痛;
  • Cloudera Manager 配置的路徑必須是絕對路徑并且所有主機(jī)都具備該路徑婚苹;
  • 在同主機(jī)上的服務(wù)可共享證書;

對每個(gè)節(jié)點(diǎn)上的 cms.keystore.${HOSTNAME} 進(jìn)行重命名鸵膏,cp 成一個(gè)通用的名字膊升,這樣才可以匹配 HDFS 的配置:

pscp -h list_all rename_jks.sh /tmp
pssh -h list_all "sudo /usr/bin/bash /tmp/rename_jks.sh"

其中腳本 rename_jks.sh 內(nèi)容如下:

#!/bin/bash
HOSTNAME=`hostname -f`
sudo cp /opt/cloudera/security/jks/cms.keystore.${HOSTNAME} /opt/cloudera/security/jks/cms.keystore

修改 HDFS 配置后重啟,PASSWD 為上一篇中設(shè)置的 JKS 密碼:

ssl.server.keystore.location=${BASE_SECURITY_PATH}/jks/cms.keystore
ssl.server.keystore.password=${PASSWD}
ssl.server.keystore.keypassword=${PASSWD}
ssl.client.truststore.location=${JAVA_HOME}/jre/lib/security/jssecacerts.public
ssl.client.truststore.password=${PASSWD}
hadoop.ssl.enabled=true
dfs.datanode.address = 1024
dfs.data.transfer.protection = privacy

配置 YARN 加密

修改 YARN 配置后重啟较性,PASSWD 為上一篇中設(shè)置的 JKS 密碼:

ssl.server.keystore.location=${BASE_SECURITY_PATH}/jks/cms.keystore
ssl.server.keystore.password=${PASSWD}
ssl.server.keystore.keypassword=${PASSWD}
ssl.client.truststore.location=${JAVA_HOME}/jre/lib/security/jssecacerts.public
ssl.client.truststore.password=${PASSWD}

配置 HBase 加密

修改 HBase 配置后重啟用僧,PASSWD 為上一篇中設(shè)置的 JKS 密碼:

hdaoop.ssl.enabled, hbase.ssl.enabled = true
ssl.server.keystore.location = ${BASE_SECURITY_PATH}/jks/cms.keystore
ssl.server.keystore.password=${PASSWD}
ssl.server.keystore.keypassword=${PASSWD}
 
hbase.rest.ssl.enabled = true
hbase.rest.ssl.keystore.store = ${BASE_SECURITY_PATH}/jks/cms.keystore
hbase.rest.ssl.keystore.password = ${PASSWD}
hbase.rest.ssl.keystore.keypassword = ${PASSWD}
 
hbase.thrift.ssl.enabled = true
hbase.thrift.ssl.keystore.store = ${BASE_SECURITY_PATH}/jks/cms.keystore
hbase.thrift.ssl.keystore.password = ${PASSWD}
hbase.thrift.ssl.keystore.keypassword = ${PASSWD}

配置 HiveServer2 加密

相比較SASL QOP傳輸加密,SSL加密在大數(shù)據(jù)請求情況下性能更好赞咙,所以選擇SSL责循。修改 Hive 配置后重啟,PASSWD 為上一篇中設(shè)置的 JKS 密碼攀操,請注意替換 BASE_SECURITY_PATH PASSWD::

hive.server2.enable.SSL, hive.server2.use.SSL = true
hive.server2.keystore.path = ${BASE_SECURITY_PATH}/jks/cms.keystore
hive.server2.keystore.password =${PASSWD}
hive.server2.webui.keystore.password = ${PASSWD}
hive.server2.webui.keystore.path = ${BASE_SECURITY_PATH}/jks/cms.keystore

配置到此院仿,HUE 中的 Oozie Editor 的 Hive 作業(yè)會(huì)運(yùn)行失敗,我們可以通過 beeline 進(jìn)行測試:

kdestroy
kinit hive/hive_admin

HIVE_SERVER2_HOSTNAME=192.168.1.3
beeline -u "jdbc:hive2://${HIVE_SERVER2_HOSTNAME}:10000/default;principal=hive/${HIVE_SERVER2_HOSTNAME}@DOMAIN.COM;ssl=True;sslTrustStore=${JAVA_HOME}/jre/lib/security/jssecacerts.public;trustStorePassword=${PSSWD};"

配置 HUE 加密

HUE 作為客戶端

HUE 在和 HBase速和、Oozie歹垫、HDFS、YRAN 進(jìn)行交互的時(shí)候是作為客戶端的颠放,所以 HUE 必須具有所有這些服務(wù)的證書排惨,并保存在可信庫中,因?yàn)?HUE 是基于 Python 編寫碰凶,所以可信庫是 PEM 格式暮芭。

執(zhí)行腳本鹿驼,在每臺主機(jī)上生成 PEM 格式密鑰庫:

pscp -h list_all generate_pem_ca.sh /tmp
pssh -h list_all "sudo /usr/bin/bash /tmp/generate_pem_ca.sh"

其中腳本 generate_pem_ca.sh 的內(nèi)容如下,請為 JAVA_HOME 進(jìn)行賦值:

#!/bin/bash
 
JAVA_HOME=${JAVA_HOME}
HOSTNAME=`hostname -f`
BASE_SECURITY_PATH=/opt/cloudera/security
 
sudo ${JAVA_HOME}/bin/keytool -exportcert -keystore ${BASE_SECURITY_PATH}/jks/cms.keystore.${HOSTNAME} -alias cms.${HOSTNAME} -storepass ${PASSWD} -file ${BASE_SECURITY_PATH}/jks/cms.keystore.hue.${HOSTNAME}
 
sudo openssl x509 -inform der -in ${BASE_SECURITY_PATH}/jks/cms.keystore.hue.${HOSTNAME} > /tmp/cms.pem.hue.${HOSTNAME}
sudo cp /tmp/cms.pem.hue.${HOSTNAME} ${BASE_SECURITY_PATH}/x509/
sudo chown cloudera-scm.cloudera-scm ${BASE_SECURITY_PATH}/x509/cms.pem.hue.${HOSTNAME}

整合密鑰庫辕宏,生成公共可信庫:

for agent in `cat list_agents_hostname`;do scp ${agent}:/tmp/cms.pem.hue.${agent} /tmp;done;

# 執(zhí)行腳本 生成 HUE 公共可信庫
#!/bin/bash
for agent in `cat list_agents_hostname`
do 
    pem_list="${pem_list} cms.pem.hue.${agent}"
done
cat ${pem_list} > /tmp/cms.pem.hue.public
 
# 分發(fā)公共可信庫 cms.pem.hue.public
pscp -h list /tmp/cms.pem.hue.public /tmp
pssh -h list "sudo cp /tmp/cms.pem.hue.public /opt/cloudera/security/x509"
pssh -h list "sudo chown cloudera-scm.cloudera-scm /opt/cloudera/security/x509/cms.pem.hue.public"

修改 HUE 配置:

ssl_cacerts = /opt/cloudera/security/x509/cms.pem.hue.public

因?yàn)槭亲院灻荑€畜晰,需要修改環(huán)境變量,Hue Service Environment Advanced Configuration Snippet

REQUESTS_CA_BUNDLE = /opt/cloudera/security/x509/cms.pem.hue.public

重啟 HUE 服務(wù)瑞筐,請注意凄鼻,此時(shí) HUE 的 Oozie Editor 中 Hive 作業(yè)仍運(yùn)行失敗。

HUE 作為服務(wù)端

我們不使用 HUE 自帶的 LoadBalancer聚假,使用 Nginx 替代块蚌。在 HUE Server 上執(zhí)行如下操作:

sudo -u cloudera-scm cp /opt/cloudera/security/x509/cms.key.${HOSTNAME} /opt/cloudera/security/x509/cms.key.hue-server
sudo -u cloudera-scm cp /opt/cloudera/security/x509/cms.pem.${HOSTNAME} /opt/cloudera/security/x509/cms.pem.hue-server

修改 HUE 配置后重啟,請注意替換 PASSWD::

Enable TLS/SSL for Hue = true
ssl_certificate = /opt/cloudera/security/x509/cms.pem.hue-server
ssl_private_key = /opt/cloudera/security/x509/cms.key.hue-server
ssl_password = ${PASSWD}

Nginx 的安裝請參考網(wǎng)上教程魔策,假設(shè) Nginx 服務(wù)器 (192.168.1.1) 已經(jīng)生成過 JKS 密鑰匈子,我們需要配置 Nginx 免密鑰訪問 HUE Server:

sudo cp /opt/cloudera/security/x509/cms.key.${HOSTNAME} /opt/cloudera/security/x509/cms.key.nginx
sudo cp /opt/cloudera/security/x509/cms.key.nginx /opt/cloudera/security/x509/cms.key.nginx.bak
sudo openssl rsa -in /opt/cloudera/security/x509/cms.key.nginx.bak -out /opt/cloudera/security/x509/cms.key.nginx

配置 Nginx 實(shí)現(xiàn) LoadBalancer:

server {
    server_name 192.168.1.1;
    charset utf-8;
 
    listen 8889 ssl;
    ssl_certificate /opt/cloudera/security/x509/cms.pem.nginx;
    ssl_certificate_key /opt/cloudera/security/x509/cms.key.nginx;
 
    client_max_body_size 0;
    location / {
        proxy_pass https://hue;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $remote_addr;
    }
 
    location /static/ {
        alias /opt/cloudera/parcels/CDH/lib/hue/build/static/;
 
        expires 30d;
        add_header Cache-Control public;
    }
}
 
upstream hue {
    ip_hash;
 
    # List all the Hue instances here for high availability.
    server HUE_HOSTNAME1:8888 max_fails=3;
    server HUE_HOSTNAME2:8888 max_fails=3;
    ...
}

配置 HUE Server 和 HiveServer2 之間的加密,通過 Cloudera Manager Admin Console 對 hue.ini 進(jìn)行追加配置闯袒,配置項(xiàng)為 Hue Service Advanced Configuration Snippet (Safety Valve) for hue_safety_valve.ini

[beeswax]
    [[ssl]]
    enabled = true
    cacerts = /opt/cloudera/security/x509/cms.pem.hue.public
    validate = true

重啟 HUE 服務(wù)。

配置 Impala 加密

配置 HUE 和 ImpalaD 傳輸加密

該場景下 HUE 作為客戶端游岳,ImapalD 作為服務(wù)端政敢。和 HUE 一樣,需要使用到服務(wù)端的公共可信庫和客戶端的密鑰庫:

#/bin/bash
HOSTNAME=`hostname -f`
BASE_SECURITY_PATH=/opt/cloudera/security/x509
 
# 生成 ImpalaD 服務(wù)端 CA胚迫、Key
sudo -u cloudera-scm cp ${BASE_SECURITY_PATH}/x509/cms.key.${HOSTNAME} ${BASE_SECURITY_PATH}/x509/cms.key.impala
sudo -u cloudera-scm cp ${BASE_SECURITY_PATH}/x509/cms.pem.${HOSTNAME} ${BASE_SECURITY_PATH}/x509/cms.pem.impala
 
# 生成客戶端可信庫
sudo -u cloudera-scm cp ${BASE_SECURITY_PATH}/x509/cms.pem.hue.public ${BASE_SECURITY_PATH}/x509/cms.pem.impala.public

修改 Impala 配置后重啟喷户,請注意替換 BASE_SECURITY_PATH PASSWD

client_services_ssl_enabled = true
ssl_server_certificate = webserver_certificate_file = ${BASE_SECURITY_PATH}/x509/cms.pem.impala
ssl_private_key = webserver_private_key_file = ${BASE_SECURITY_PATH}/x509/cms.key.impala
ssl_private_key_password_cmd = webserver_private_key_password_cmd = ${PASSWD}
ssl_client_ca_certificate = ${BASE_SECURITY_PATH}/x509/cms.key.impala.public

修改 HUE 配置,在 hue.ini 中添加和 Impala 的傳輸加密配置访锻,配置項(xiàng)為 Hue Service Advanced Configuration Snippet (Safety Valve) for hue_safety_valve.ini

[impala]
    [[ssl]]
    enabled = true
    cacerts = /opt/cloudera/security/x509/cms.pem.hue.public
    validate = true

重啟 HUE 服務(wù)褪尝,然后我們可以在 Impala Editor 中對 SQL 操作進(jìn)行驗(yàn)證,確認(rèn)加密調(diào)整后的功能無誤期犬。

配置 StateStore 傳輸加密

修改 Impala 配置后重啟河哑,請注意替換 BASE_SECURITY_PATH PASSWD

webserver_certificate_file = ${BASE_SECURITY_PATH}/jks/cms.pem.impala
webserver_private_key_file = ${BASE_SECURITY_PATH}/jks/cms.key.impala
webserver_private_key_password_cmd = ${PASSWD}

配置 ImpalaD 和 LDAP 傳輸加密

該場景下 ImpalaD 作為客戶端,LDAP 作為服務(wù)端龟虎。修改 Impala 配置后重啟璃谨,請注意替換 BASE_SECURITY_PATH

ldap_ca_certificate = ${BASE_SECURITY_PATH}/jks/cms.pem.impala

配置 HAProxy 做前端轉(zhuǎn)發(fā)鲤妥、SSL穿透

做穿透并且不在 HUE 層面做 LoadBalancer 的目的是:

  • 給到的 SSL 配置是 PEM 格式佳吞,但是信任庫卻是 JKS 格式,所以無法實(shí)現(xiàn) SSL 轉(zhuǎn)發(fā)棉安,只能做穿透底扳,而 Nginx 無法做 SSL 穿透,所以選擇了 HAProxy贡耽,同時(shí)運(yùn)維兩套負(fù)載均衡是一個(gè)待優(yōu)化的點(diǎn)衷模;
  • 公司內(nèi)部網(wǎng)絡(luò)隔離必須使用前端轉(zhuǎn)發(fā)和反向代理羡滑;
  • 在配置中啟用了 LoadBalancer 之后,HUE 無法訪問 Impala算芯,這塊暫時(shí)沒時(shí)間調(diào)研柒昏;

修改 /etc/haproxy/haproxy.cfg

frontend f_impala_jdbc
    bind 0.0.0.0:21050
    mode tcp
    default_backend b_impala_jdbc
 
backend b_impala_jdbc
    mode tcp
    balance roundrobin
    stick-table type ip size 200k expore 30m
    stick on src
    server b_impala_jdbc_01 ${IMPALA_DAEMON_01}:21050
    server b_impala_jdbc_01 ${IMPALA_DAEMON_02}:21050
    ...

重啟 HAProxy 后配置生效,假設(shè) HAProxy 架設(shè)在 192.168.1.1熙揍,我們可以通過 https://192.168.1.1:21050 去訪問 ImpalaD 服務(wù)职祷。

配置 Oozie 加密

修改配置后重啟,請注意替換 BASE_SECURITY_PATH PASSWD JAVA_HOME

Enable TLS/SSL for Oozie = true
Oozie TLS/SSL Server JKS Keystore File Location = ${BASE_SECURITY_PATH}/jks/cms.keystore
Oozie TLS/SSL Server JKS Keystore File Password = ${PASSWD}
Oozie TLS/SSL Certificate Trust Store File = ${JAVA_HOME}/jre/lib/security/jssecacerts.public
Oozie TLS/SSL Certificate Trust Store Password = ${PASSWD}

配置 HDFS HTTPFS 加密

修改配置后重啟届囚,請注意替換 BASE_SECURITY_PATH PASSWD JAVA_HOME

Enable TLS/SSL for HttpFS = true
HttpFS TLS/SSL Server JKS Keystore File Location = ${BASE_SECURITY_PATH}/jks/cms.keystore
HttpFS TLS/SSL Server JKS Keystore File Password = ${PASSWD}
HttpFS TLS/SSL Certificate Trust Store File = ${JAVA_HOME}/jre/lib/security/jssecacerts.public
HttpFS TLS/SSL Certificate Trust Store Password = ${PASSWD}

小結(jié)

本篇介紹了如何對 Hadoop 核心組件配置傳輸層加密有梆。在每次配置后,最直觀的測試方式就是在 HUE 中對各組件的功能模塊進(jìn)行黑盒集成測試意系。比如配置了 HDFS 加密后泥耀,我們可以對 FileBrowser 進(jìn)行訪問;配置了 HBase 加密后蛔添,我們可以對 HBase 進(jìn)行查詢訪問痰催;配置了 HiveServer2 加密后,我們可以對 Hive Editor Impala Editor 進(jìn)行查詢訪問迎瞧。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末夸溶,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子凶硅,更是在濱河造成了極大的恐慌缝裁,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件足绅,死亡現(xiàn)場離奇詭異捷绑,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)氢妈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進(jìn)店門粹污,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人允懂,你說我怎么就攤上這事厕怜。” “怎么了蕾总?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵粥航,是天一觀的道長。 經(jīng)常有香客問我生百,道長递雀,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任蚀浆,我火速辦了婚禮缀程,結(jié)果婚禮上搜吧,老公的妹妹穿的比我還像新娘。我一直安慰自己杨凑,他們只是感情好滤奈,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著撩满,像睡著了一般蜒程。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上伺帘,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天昭躺,我揣著相機(jī)與錄音,去河邊找鬼伪嫁。 笑死领炫,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的张咳。 我是一名探鬼主播帝洪,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼晶伦!你這毒婦竟也來了碟狞?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤婚陪,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后频祝,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體泌参,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年常空,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了沽一。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,696評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡漓糙,死狀恐怖铣缠,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情昆禽,我是刑警寧澤蝗蛙,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站醉鳖,受9級特大地震影響捡硅,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜盗棵,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一壮韭、第九天 我趴在偏房一處隱蔽的房頂上張望北发。 院中可真熱鬧,春花似錦喷屋、人聲如沸琳拨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽狱庇。三九已至,卻和暖如春是牢,著一層夾襖步出監(jiān)牢的瞬間僵井,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工驳棱, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留批什,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓社搅,卻偏偏與公主長得像驻债,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子形葬,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評論 2 353

推薦閱讀更多精彩內(nèi)容