授之以渔-运维平台应用模块三(BIND篇)

暴雪爸爸开了8.0,我去保卫艾泽拉斯了,很久没有更新。公司用的BIND做的DNS管理,采用了文本格式存储。之前用过BIND+MYSQL+DLZ,对于后面想要自行搭建运维可视化平台的小伙伴来说,确实很方便。但性能问题是个大问题,最后无奈采用通过Dnspython封装的BIND接口,操作BIND的jnl文件进行动态解析。

附上一个dlz和原生bind的性能测试数据(比较老,仅供参考):


image.png

效果图如下:


image.png

image.png

image.png

一、 Jnl文件

jnl 文件(journal文件)是bind动态更新的时候记录更新内容所生成的日志文件。BIND9支持两个授予用户对一个域执行动态更新权限的备选方案,分别由allow-update和update-policy设定。其中allow-update 授于指定用户对域中的任何名称的任何的记录更新的权利。allow-update指定哪些主机允许为主域名服务器提交动态 DNS 更新。默认为拒绝任何主机进行更新,详见百度。

二、 环境准备

三、 食用过程

1.生成TSIG key,修改named.conf添加授权,定义zone文件添加allow-update(详见百度,这里不具体展开)

2.增删改后端部分代码

# -*- coding: utf8 -*-
import dns.tsigkeyring
import dns.update
import dns.query 
import dns.resolver
keyring = dns.tsigkeyring.from_text({"youth":tsig key密码})
up = dns.update.Update("youth.cn", keyring=keyring)
up .add("test2", 60, 'a', "192.168.183.131")    #添加名称为test2的A记录,TTL时间60,解析地址192.168.183.131
up.delete("test2")  #删除test2记录
up.replace("test2", 360, "CNAME", "test3.youth.cn.")  #将test2修改为CNAME记录,TTL时间360,CNAME地址test3.youth.cn.
dns.query.tcp(up, SERVER_IP)

3.前端用的Metronic框架,jQuery表格插件用的dataTables,部分前端代码如下:

<div class="page-bar">
    <ul class="page-breadcrumb">
        <li>
            <i class="fa fa-home"></i>
            <a href="../dashboard/">主页</a>
            <i class="fa fa-angle-right"></i>           
        </li>   
        <li>
            <a href="../bind_list/">DNS管理系统</a>
            <i class="fa fa-angle-right"></i>
        </li>
        <li>
            <a href="../bind_list/" id="history_url">DNS管理系统汇总</a>
        </li>
    </ul>
</div>

<div class="portlet">
    <form class="tel_search-form" method="get" action="">
        <div class="row">
            <div class="col-md-12">
                <div class="input-group input-xlarge">
                    {%  for i in  user.groups.values %}{% ifequal i.name 'admin' %}
                    <div class="input-group-btn">
                        <select class="form-control input-small" name="bind_zone">
                            <option value=""> 请选择记录域 </option>
                            <option value="2"> youth.cn </option>
                            <option value="1"> k618.cn </option>
                            <option value="3"> ccyl.org.cn </option>
                            <option value="4"> gqt.org.cn </option>
                        </select>
                    </div>
                    {% else %}{% endifequal %}{% endfor %}
                    <div class="input-group-btn">
                        <select class="form-control input-small" name="bind_type">
                            <option value=""> 请选择记录类型 </option>
                            <option value="1"> A记录 </option>
                            <option value="2"> AAAA记录 </option>
                            <option value="6"> CNAME记录 </option>
                            <option value="3"> MX记录 </option>
                            <option value="5"> TXT记录 </option>
                            <option value="4"> NS记录 </option>
                        </select>
                    </div>
                    <div class="input-group-btn">
                        <select class="form-control input-medium" name="bind_internal_external">
                            <option value=""> 请选择内外部解析类型 </option>
                            <option value="1"> 内部解析 </option>
                            <option value="2"> 外部解析</option>
                        </select>
                    </div>
                    <input type="text" name="search" placeholder="请输入查询名或者服务器IP " class="form-control input-large">
                    <span class="input-group-btn">  
                        <button data-loading-text="等待提交..." class="loading-btn btn green" type="submit">查找 <i class="fa fa-search"></i></button>
                        <a class="btn red" href="#responsive" margin-bottomrole="button" data-toggle="modal"><span > 添加DNS解析记录<i class="fa fa-plus"> </i></span></a>
                    </span>                 
                </div>
            </div>  
        </div>
    </form> 
</div>

<div class="portlet box green">
    <div class="portlet-title">
        <div class="caption"> <i class="icon-globe"> </i> DNS解析记录汇总 </div>
        <div class="tools"> <a href="javascript:;" class="collapse"> </a> <a href="javascript:;" class="reload"> </a> <a href="javascript:;" class="remove"> </a> </div>
    </div>
    <div class="portlet-body">
        <table class="table table-striped table-bordered table-condensed" id="bindlist">
            <thead>
                <tr>
                    <th><b> ID </b> </th>
                    <th><b> 名称 </b> </th>
                    <th><b> 域 </b> </th>
                    <th><b> 类型 </b> </th>
                    <th><b> 内部/外部 </b> </th>
                    <th><b> 解析地址 </b> </th>
                    <th><b> TTL </b> </th>
                    <th><b> 备注解析地址 </b> </th>
                    <th><b> 更改时间 </b> </th>
                    <th><b> 查看状态 </b> </th>
                    <th><b> 更改操作 </b> </th>
                    <th><b> 删除操作 </b> </th>
                </tr>
            </thead>
            <tbody>
                {% for bind in binds%}
                <tr>
                    <td id={{ bind.id }}> {{ bind.id }} </td>
                    <td id={{ bind.bind_name }}> {{ bind.bind_name }} </td>
                    <td id={{bind.bind_zone_id}}>
                       {% ifequal  bind.bind_zone_id '1' %}
                        <span class="label label-sm label-success">
                        k618.cn
                        </span>
                        {% endifequal %}
                       {% ifequal  bind.bind_zone_id '2' %}
                        <span class="label label-sm label-danger">
                        youth.cn
                        </span>
                        {% endifequal %}
                       {% ifequal  bind.bind_zone_id '3' %}
                        <span class="label label-sm label-warning">
                        ccyl.org.cn
                        </span>
                        {% endifequal %}
                       {% ifequal  bind.bind_zone_id '4' %}
                        <span class="label label-sm label-info">
                        gqt.org.cn
                        </span>
                        {% endifequal %}
                    </td>
                    <td id={{ bind.bind_type_id}}>
                       {% ifequal  bind.bind_type_id '1' %}
                        <span class="label label-sm label-warning">
                        A记录
                        </span>
                        {% endifequal %}
                       {% ifequal  bind.bind_type_id '6' %}
                        <span class="label label-sm label-info">
                        CNAME记录
                        </span>
                        {% endifequal %}
                       {% ifequal  bind.bind_type_id '3' %}
                        <span class="label label-sm label-success">
                        MX记录
                        </span>
                        {% endifequal %}
                       {% ifequal  bind.bind_type_id '4' %}
                        <span class="label label-sm label-danger">
                        NS记录
                        </span>
                       {% endifequal %}
                       {% ifequal  bind.bind_type_id '2' %}
                        <span class="label label-sm label-danger">
                        AAAA记录
                        </span>
                       {% endifequal %}
                       {% ifequal  bind.bind_type_id '5' %}
                        <span class="label label-sm label-danger">
                        TXT记录
                        </span>
                        {% endifequal %}
                    </td>
                    <td id={{bind.bind_internal_external}}>
                       {% ifequal  bind.bind_internal_external '1' %}
                        <span class="label label-sm label-success">
                        内部解析
                        </span>
                        {% endifequal %}
                       {% ifequal  bind.bind_internal_external '2' %}
                        <span class="label label-sm label-warning">
                        外部解析
                        </span>
                        {% endifequal %}
                    </td>
                    <td id={{ bind.bind_ip}}> {{ bind.bind_ip}} </td>
                    <td id={{ bind.bind_ttl}}> {{ bind.bind_ttl}} </td>
                    <td id={{ bind.bind_intro}}> {{ bind.bind_intro}} </td>
                    <td> {{ bind.bind_time|date:"Y-m-d H:i:s"}} </td>
                    <td><a class="fa fa-eye" href="../bind_see/?bind_name={{bind.bind_name}}&bind_zone={{bind.bind_zone}}&bind_ip={{bind.bind_ip}}"></a></td>
                    <td><a class="fa fa-edit" href="#responsives2" data-toggle="modal"></a></td>
                    <td><a class="fa fa-trash-o" href="#responsivess" data-toggle="modal"></a></td>
                {% endfor %}
                </tr>
            </tbody>
        </table>
    </div>
</div>

<div class="modal fade" id="responsive" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-hidden="true"> × </button>
                <h3 id="myModalLabel"> 添加DNS解析记录 </h3>
            </div>
            <form action="" method="post" class="form-horizontal">
                    {% csrf_token %}
                <div class="modal-body">
                    <div class="form-group">
                        <label class="control-label col-md-3"> 名称 </label>
                        <div class="col-md-5">
                            <input type="text" class="form-control" placeholder="例如:cms" name="bind_name">
                        </div>
                    </div>
                    <div class="form-group" >
                        <label class="control-label col-md-3"> TTL </label>
                        <div class="col-md-5">
                            <input type="text" class="form-control" placeholder="例如:3600" name="bind_ttl">
                        </div>
                    </div>
                    <div class="form-group">
                        <label class="control-label col-md-3"> Zone域 </label>
                        <div class="col-md-5">
                            <select class="form-control input-medium select2me select2-offscreen" name="bind_zone">
                                <option value="2"> youth.cn </option>
                                <option value="1"> k618.cn </option>
                                <option value="3"> ccyl.org.cn </option>
                                <option value="4"> gqt.org.cn </option>                                             
                            </select>
                        </div>
                    </div>
                    <div class="form-group">
                        <label class="control-label col-md-3"> 类型 </label>
                        <div class="col-md-5">
                            <select class="form-control input-medium select2me select2-offscreen" name="bind_type"  onchange="add_bind_intro_hidden(this)">
                                <option value="1"> A记录 </option>
                                <option value="2"> AAAA记录 </option>
                                <option value="6"> CNAME记录 </option>
                                <option value="3"> MX记录 </option>
                                <option value="5"> TXT记录 </option>
                                <option value="4"> NS记录 </option>
                            </select>
                        </div>
                    </div>
                    <div class="form-group">
                        <label class="control-label col-md-3"> 解析地址 </label>
                        <div class="col-md-5">
                            <input type="text" class="form-control" placeholder="例如:123.103.56.246" name="bind_ip">
                        </div>
                    </div>
                    <div class="form-group" id="add_bind_intro" style="display:none;">
                        <label class="control-label col-md-3"> 备注解析地址 </label>
                        <div class="col-md-5">
                            <input type="text" class="form-control" placeholder="例如:123.103.56.246" name="bind_intro">
                        </div>
                    </div>
                    <div class="form-group">
                        <label class="control-label col-md-3"> 解析类型 </label>
                        <div class="col-md-5">
                            <select class="form-control input-medium select2me select2-offscreen" name="bind_internal_external" onchange="edit_bind_internal_external_hidden(this)">
                                <option value="1"> 内部解析 </option>
                                <option value="2"> 外部解析 </option>
                            </select>
                        </div>
                    </div>
                    <div class="form-group" id="add_bind_url_mitors" style="display:none;">
                        <label class="control-label col-md-3">URL监控</label>
                        <div class="col-md-5">
                            <div class="basic-toggle-button" >
                                <input type="checkbox" class="make-switch" id="add_url_mitor" checked="checked" data-size="small"/>
                                <input type="hidden" name="add_url_mitors" value="true" id="add_url_mitors"/>
                            </div>
                        </div>
                    </div>
                    <div class="form-group" id="add_bind_syncs" style="display:none;">
                        <label class="control-label col-md-3">同步网宿节点</label>
                        <div class="col-md-5">
                            <div class="basic-toggle-button" >
                                <input type="checkbox" class="make-switch" id="add_sync" checked="checked" data-size="small"/>
                                <input type="hidden" name="add_syncs" value="true" id="add_syncs"/>
                            </div>
                        </div>
                    </div>
                </div>
                <div class="modal-footer">
                    <button data-loading-text="等待提交..." class="loading-btn btn green" type="submit" name="submit"> 确认执行 </button>
                    <button class="btn red" data-dismiss="modal" aria-hidden="true"> 取消执行 </button>
                </div>
            </form>
        </div>  
    </div>      
</div>

<div class="modal fade" id="responsivess" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-hidden="true"> × </button>
                <input type="hidden" id="del_name">
            </div>
            <form action="" method="get" class="form-horizontal">
                    {% csrf_token %}
                <div class="modal-body">
                    <div class="form-group">
                        <div class="col-md-5">
                            <span class="label label-danger">注意:删除解析记录,相应的监控记录也会一并删除!!</span>
                        </div>
                    </div>
                </div>
                <div class="modal-footer">
                    <label class="control-label"> </label>
                    <div class="controls">
                        <button data-loading-text="等待提交..." class="loading-btn btn green" type="submit" name="submit"> 确认执行 </button>
                        <button class="btn red" data-dismiss="modal" aria-hidden="true"> 取消执行 </button>
                    </div>
                </div>
            </form>
        </div>
    </div>
</div>

<div class="modal fade" id="responsives2" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-hidden="true"> × </button>
                <h3 id="myModalLabel"> 修改DNS解析记录 </h3>
            </div>
            <form action="" method="post" class="form-horizontal">
                    {% csrf_token %}
                <div class="modal-body">
                    <div class="form-group" type="hidden">
                        <div class="col-md-5">
                            <input type="text" id="edit_bind_id">
                        </div>
                    </div>
                    <div class="form-group">
                        <label class="control-label col-md-3"> 名称 </label>
                        <div class="col-md-5">
                            <input type="text" id="edit_bind_name">
                        </div>
                    </div>
                    <div class="form-group" >
                        <label class="control-label col-md-3"> TTL </label>
                        <div class="col-md-5">
                            <input type="text" id="edit_bind_ttl">
                        </div>
                    </div>
                    <div class="form-group">
                        <label class="control-label col-md-3"> Zone域 </label>
                        <div class="col-md-5">
                            <select class="form-control input-medium select2me select2-offscreen" name="bind_zone" id="edit_bind_zone">
                                <option value="2"> youth.cn </option>
                                <option value="1"> k618.cn </option>
                                <option value="3"> ccyl.org.cn </option>
                                <option value="4"> gqt.org.cn </option>
                            </select>
                        </div>
                    </div>
                    <div class="form-group">
                        <label class="control-label col-md-3"> 类型 </label>
                        <div class="col-md-5">
                            <select class="form-control input-medium select2me select2-offscreen" name="bind_type"  id="edit_bind_type" onchange="edit_bind_intro_hidden(this)">
                                <option value="1"> A记录 </option>
                                <option value="2"> AAAA记录 </option>
                                <option value="6"> CNAME记录 </option>
                                <option value="3"> MX记录 </option>
                                <option value="5"> TXT记录 </option>
                                <option value="4"> NS记录 </option>
                            </select>
                        </div>
                    </div>
                    <div class="form-group">
                        <label class="control-label col-md-3"> 解析地址 </label>
                        <div class="col-md-5">
                            <input type="text" id="edit_bind_ip">
                        </div>
                    </div>
                    <div class="form-group" id="edit_bind_intro" style="display:none;">
                        <label class="control-label col-md-3"> 备注解析地址 </label>
                        <div class="col-md-5">
                            <input type="text" id="edit_bind_intros">
                        </div>
                    </div>
                </div>
                <div class="modal-footer">
                    <button data-loading-text="等待提交..." class="loading-btn btn green" type="submit" name="submit"> 确认执行 </button>
                    <button class="btn red" data-dismiss="modal" aria-hidden="true"> 取消执行 </button>
                </div>
            </form>
        </div>
    </div>
</div>

这块做了一个异步的查询,其实就是点击+号,能返回到这个域名绑定的公网IP所对应的主机,效果图如下:


image.png
var TableAdvanced = function () {

    var initTable4 = function () {
        var table = $('#bindlist');

        var nCloneTh = document.createElement('th');
        nCloneTh.className = "table-checkbox";

        var nCloneTd = document.createElement('td');
        nCloneTd.innerHTML = '<span class="row-details row-details-close"></span>';

        table.find('thead tr').each(function () {
            this.insertBefore(nCloneTh, this.childNodes[0]);
        });

        table.find('tbody tr').each(function () {
            this.insertBefore(nCloneTd.cloneNode(true), this.childNodes[0]);
        });

        var oTable = table.dataTable({

            // Internationalisation. For more info refer to http://datatables.net/manual/i18n
            "language": {
                "aria": {
                    "sortAscending": ": activate to sort column ascending",
                    "sortDescending": ": activate to sort column descending"
                },
                "emptyTable": "未有相关数据",
                "info": "当前显示 _START_ 到 _END_ 条,共 _TOTAL_ 条记录。",
                "infoEmpty": "当前显示0到0条,共0条记录",
                "infoFiltered": "(数据库中共为 _MAX_ 条记录)",
                "lengthMenu": "显示 _MENU_ 记录",
                "search": "模糊查询:",
                "zeroRecords": "对不起,查询不到任何相关数据",
               "oPaginate": {
                   "sFirst": "首页",
                   "sPrevious": " 上一页 ",
                   "sNext": " 下一页 ",
                   "sLast": " 尾页 "
               }                
            },

            "columnDefs": [{
                "orderable": false,
                "targets": [0]
            }],
            "order": [
                [9, 'dec']
            ],
            "lengthMenu": [
                [5, 15, 20, -1],
                [5, 15, 20, "All"] // change per page values here
            ],
            // set the initial value
            "pageLength": 10
        });

        var tableWrapper = $('#sample_4_wrapper'); // datatable creates the table wrapper by adding with id {your_table_jd}_wrapper
        var tableColumnToggler = $('#sample_4_column_toggler');

        /* modify datatable control inputs */
        tableWrapper.find('.dataTables_length select').select2(); // initialize select2 dropdown
        table.on('click', ' tbody td .row-details', function () {
            var nTr = $(this).parents('tr')[0];
            if (oTable.fnIsOpen(nTr)) {
                $(this).addClass("row-details-close").removeClass("row-details-open");
                oTable.fnClose(nTr);
            } else {
                var ip = $(this).parent().parent().find('td').eq(6).attr("id");
                var type = $(this).parent().parent().find('td').eq(4).attr("id");
                var intro = $(this).parent().parent().find('td').eq(8).attr("id");
                $(this).addClass("row-details-open").removeClass("row-details-close");;
                fnFormatDetails(nTr, $(this).attr("data_id"),ip,type,intro);
            }
        });
          function fnFormatDetails(nTr, pdataId, ip ,type ,intro) {
                var aData = oTable.fnGetData(nTr);
               //根据配置Id 异步查询数据
                $.ajax({
                       type:'get',
                       url:"../bind_host_get/?ip="+ip+"&type="+type+"&intro="+intro,
                       data:{"pdataId":pdataId},
                       dataType:"json",
                       async:true,
                       beforeSend:function(xhr){//信息加载中
                           oTable.fnOpen( nTr, '<span id="configure_chart_loading"><img src="../assets/global/img/input-spinner.gif"/> 详细信息加载中...</span>', 'details' );
                       },
                       success:function (obj){
                               var sOut = '<table class="table table-striped table-bordered table-hover">';
                               for(var id in obj){
                                    sOut += '<tr><td>'+id+'</td><td>' + obj[id] + '</td></tr>';
                               }
                               sOut+='</table>';
                               oTable.fnOpen( nTr,sOut, 'details' );

                       },
                       error: function(){//请求出错处理
                           oTable.fnOpen( nTr,'加载数据超时', 'details' );
                       }
                   });

           }

        /* handle show/hide columns*/
        $('input[type="checkbox"]', tableColumnToggler).change(function () {
            /* Get the DataTables object again - this is not a recreation, just a get of the object */
            var iCol = parseInt($(this).attr("data-column"));
            var bVis = oTable.fnSettings().aoColumns[iCol].bVisible;
            oTable.fnSetColumnVis(iCol, (bVis ? false : true));
        });
    }

    return {

        //main function to initiate the module
        init: function () {

            if (!jQuery().dataTable) {
                return;
            }

            console.log('me 1');


            initTable4();


            console.log('me 2');
        }

    };

}();

这里踩过的坑:

最终公司的DNS惨遭了30G的DD,导致运营商都跟着一起倒霉,后续将NS解析迁移至网宿的云DNS平台,我的平台还是通过网宿的云DNS平台所提供的接口API进行域名解析,BIND只作为内网解析及解析记录汇总(即选择外部解析后,解析记录将存储在我的内部平台上并推送记录到网宿节点,这也是为了将来万一换厂家,直接推送全部记录即可)


image.png

URL监控用的Openfalcon做的,后续会慢慢补上。。。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,602评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,442评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,878评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,306评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,330评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,071评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,382评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,006评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,512评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,965评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,094评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,732评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,283评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,286评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,512评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,536评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,828评论 2 345

推荐阅读更多精彩内容