我想使用python创建一个CA证书以及我用它签名的客户端证书。我将在OpenVPN中使用它们。经过几天的研究和反复试验,这是我想出的:
#!/usr/bin/env python
import os
import sys
import random
from OpenSSL import crypto
###########
# CA Cert #
###########
ca_key = crypto.PKey()
ca_key.generate_key(crypto.TYPE_RSA, 2048)
ca_cert = crypto.X509()
ca_cert.set_version(2)
ca_cert.set_serial_number(random.randint(50000000,100000000))
ca_subj = ca_cert.get_subject()
ca_subj.commonName = "My CA"
ca_cert.add_extensions([
crypto.X509Extension("subjectKeyIdentifier", False, "hash", subject=ca_cert),
])
ca_cert.add_extensions([
crypto.X509Extension("authorityKeyIdentifier", False, "keyid:always", issuer=ca_cert),
])
ca_cert.add_extensions([
crypto.X509Extension("basicConstraints", False, "CA:TRUE"),
crypto.X509Extension("keyUsage", False, "keyCertSign, cRLSign"),
])
ca_cert.set_issuer(ca_subj)
ca_cert.set_pubkey(ca_key)
ca_cert.sign(ca_key, 'sha256')
ca_cert.gmtime_adj_notBefore(0)
ca_cert.gmtime_adj_notAfter(10*365*24*60*60)
# Save certificate
with open("ca.crt", "wt") as f:
f.write(crypto.dump_certificate(crypto.FILETYPE_PEM, ca_cert))
# Save private key
with open("ca.key", "wt") …Run Code Online (Sandbox Code Playgroud) 我的django服务器以jpeg流的形式一次播放一帧视频。
看起来像这样:
class VideoCamera():
def __init__(self):
# code
def get_frame(self):
# code
return frame
def gen(camera):
while True:
yield camera.get_frame()
def view_cam(request):
return StreamingHttpResponse(gen(VideoCamera()), content_type="multipart/x-mixed-replace;boundary=frame")
Run Code Online (Sandbox Code Playgroud)
这是实时的摄像头提要,因此流无止境。我需要在客户端断开连接时将其中断,但是到目前为止,我仍无法弄清如何检测到客户端断开连接。
我想念什么吗?
编辑:
为了消除与相机有关的一切,我这样做:
def gen():
for i in range(1000):
time.sleep(1)
print(i)
yield i
def view_cam(request):
return StreamingHttpResponse(gen(), content_type="multipart/x-mixed-replace;boundary=frame")
Run Code Online (Sandbox Code Playgroud)
并通过链接到我的视图curl -N http://localhost/my_app/view_cam/。它流传输数字,当我停止使用Ctrl + C进行卷曲时,生成器只是无限期地运行,而没有注意到客户端消失了。如果再运行几次并停止卷曲,则我的gen()功能会运行多个实例,这正是相机发生的情况。
编辑2:
该项目使用Django Channels。我只是注意到,如果我通过在settings.py中将其注释掉来禁用频道,则上面的示例可以完美地工作。我不认为渠道与问题有关,但很明显,这与某种原因有关。
频道开发服务器实际上会在10秒后检测到断开连接(不是像默认的django服务器那样立即检测到),并显示以下内容:
在/home/pi/paperless_clipboard/venv3/lib/python3.5/site-packages/channels/http.py:213>上运行的应用程序实例call()在/usr/lib/python3.5/ asyncio / futures.py:452,Task._wakeup()] >>用于连接的时间过长,无法关闭并被杀死。
但是尽管有消息说有人被杀死,但仍gen()继续运行,并向终端打印号码。
我有一个使用 Django 2.2.4 的项目。
我有一个名为 Company 的 Django 模型。
我使用 post_save 信号来确保一旦创建了新公司,就会创建一个名为“Billing”的新模型实例,该实例与该公司相关联。这包含公司的帐单信息。这很好用。
由于我的 Billing 对象与公司相关联,并且我使用on_delete=models.CASCADE,因此一旦公司被删除,与该公司关联的 Billing 对象也会自动删除。这也很好用。
由于每个公司的 Billing 对象现在与 Company 一起自动创建和删除,因此使用 Django Admin Web 界面的管理员无需手动创建或删除 Billing 对象。我想对他们隐藏这个功能。
通常,防止 Django Admin 允许某人添加或删除对象的常用方法是将其添加到 admin.py 中该模型的 ModelAdmin:
class BillingAdmin(admin.ModelAdmin):
...
# Prevent deletion from admin portal
def has_delete_permission(self, request, obj=None):
return False
# Prevent adding from admin portal
def has_add_permission(self, request, obj=None):
return False
Run Code Online (Sandbox Code Playgroud)
这有效,并且确实隐藏了管理员手动创建或删除 Billing 对象实例的能力。然而,它确实有一个负面影响:Django Admin 用户不能再删除公司。删除公司时,Django 会查找所有需要删除的关联对象,注意到不允许用户删除关联的 Billing 对象,并阻止用户删除公司。
虽然我不希望 Django Admin 用户能够手动创建或删除 Billing 模型的实例,但我仍然希望他们能够删除整个 Company,这将导致删除关联的 Billing …
按照 Rust 书中的示例使用其建议的rand = "0.6.0",我得到如下所示的代码:
use rand::Rng;
fn main() {
let secret_number = rand::thread_rng().gen_range(1, 101);
println!("The secret number is: {}", secret_number);
}
Run Code Online (Sandbox Code Playgroud)
本书后面关于模块的章节中所说的一切都表明,如果您use rand::Rng;按上述方式执行 a ,您将能够使用Rng. 如果这恰好是一个模块本身,您可以使用带有Rng::submodule. 如果这恰好是一种类型,则只需将其用作Rng. 然而,在上面的代码中,我们从不使用Rng任何地方。
相反,我们使用看似无关的rand::thread_rng(). 据我了解,既然rand是顶级 crate 的名称,我们应该能够使用它,即使没有use似乎没有做任何事情的语句。
相反,由于某种原因,如果没有该use语句,程序将无法编译。这真的很令人困惑。我希望这本书能更好地解释那里发生的事情。
为什么我们需要 use 语句?为什么我们不使用Rng?它与 有什么关系rand::thread_rng()?
我来自 Python 背景,所以我习惯于这样的想法:如果您导入threading,那么您正在使用threading.something. 如果您 import django.utils,则您正在使用django.utils.something. 这似乎是django.utils您使用完全不相关的django.urls.
锈书上说:
我们也可以在我们的板条箱中实现
Summary,Vec<T>因为aggregator该特征Summary是我们的aggregator板条箱本地的。https://doc.rust-lang.org/book/ch10-02-traits.html#implementing-a-trait-on-a-type
如果我的包使用 crates.io 中的另一个包(例如 )rand,并rand在标准库中的类型(例如 )上实现特征Vec<T>,那么我的代码是否能够看到这些方法?
我知道有一个限制,即特征必须在您使用其方法的范围内。如果rand在 上实现了自定义特征Vec<T>,并且我尝试在我的板条箱中使用该特征中的方法之一,编译器是否会告诉我需要rand在使用这些方法之前导入该特征,或者它会告诉我这些方法不不存在吗?如果是前者,如果我从 导入特征rand,我可以在 上使用这些方法吗Vec<T>?
我有一个pathlib.Path('/etc')。如果我需要为其添加前缀pathlib.Path('/mnt/chroot')并执行以下操作:
Path('/mnt/chroot') / Path('/etc')
我最终得到: PosixPath('/etc'),大概是因为两者Path都是绝对路径,并且不能连接。
我可以用类似的方法来组合解决方案:
Path('/mnt/chroot') / str(Path('/etc')).removeprefix('/')
但这是冗长、粗俗的。有没有更简单、正确的方法来做到这一点?
在 Rust 中,你可以升级一个不可变的变量:
let v = Vec::new(); // Immutable
let mut v = v; // Mutable
v.push("hi"); // Succeeds
Run Code Online (Sandbox Code Playgroud)
或者降级一个可变变量:
let mut v = Vec::new(); // Mutable
let v = v; // Immutable
v.push("hi"); // Won't compile
Run Code Online (Sandbox Code Playgroud)
我的问题是——为什么?
据我了解,用于存储变量值的底层内存永远不会是一成不变的。从技术上讲,每个内存地址都可以写入。不变性是一种人为的约束,有人为我们设置的(如内核),或者我们为自己设置的。
当我说:
let v = vec!["a", "b", "c"];
Run Code Online (Sandbox Code Playgroud)
我是说我想要一个具有这些值的内存变量,并且我不希望以后任何代码更改它。如果我试图在某个时候改变这个变量,给我一个错误。这是我定义的约束。
如果以后可以,请执行以下操作:
let mut v = v;
Run Code Online (Sandbox Code Playgroud)
使它可变,并改变它,这似乎违背了不可变变量的全部目的。在这一点上,您不妨让所有变量都可变(就像在 Python 中一样),因为不保证不变性。不仅不能保证,而且程序员可能会对不变性的保证产生错误的认识,并基于这种假设犯错误。
至少对于常量,有不变性的保证。如果您可以在任何时候使其可变,则常规不可变变量的目的尚不清楚。
我正在 docs.rs 上查看gpio_cdev 的文档。
该板条箱的可选功能之一是async-tokio,它允许您编写异步代码来检查 GPIO 引脚。gpio_cdev github 首页上有一个使用AsyncLineEventHandle.
我看到的问题是 docs.rs 文档完全没有提及AsyncLineEventHandle或与 Async 有关的任何内容。
docs.rs 网站上是否有一个按钮可以显示可选功能的文档?可选功能是否从未记录在 docs.rs 上?还是由开发人员决定在 docs.rs 上包含可选功能的文档?我应该为此提交错误报告吗?
我假设如果我使用本地生成文档,我就能够看到文档cargo doc(尽管我还没有尝试过)。这是唯一的选择吗?
编辑:确认只要我启用了该功能,本地生成的文档就会显示异步部分。
当您创建一个以多个引用作为输入的函数,并返回一个引用作为输出时,您需要指定输出引用的生命周期与哪个或多个输入引用相关联。这是有道理的。
没有意义的事情是为什么您需要定义多个通用生命周期。你只能有一个返回值。
在这里,我们定义了'a和'b- 两个通用生命周期。在返回值上,我们可以指定'a或'b- 不能同时指定:
fn foo<'a, 'b>(ref1: &'a str, ref2: &'b str) -> &'a str {}
Run Code Online (Sandbox Code Playgroud)
这似乎可以缩短为:
fn foo<'a>(ref1: &'a str, ref2: &str) -> &'a str {}
Run Code Online (Sandbox Code Playgroud)
如果我们想将输出的生命周期与第二个输入参数联系起来,我们可以这样做:
fn foo<'a>(ref1: &str, ref2: &'a str) -> &'a str {}
Run Code Online (Sandbox Code Playgroud)
如果我们想将它与两者联系起来,我们可以这样做:
fn foo<'a>(ref1: &'a str, ref2: &'a str) -> &'a str {}
Run Code Online (Sandbox Code Playgroud)
这涵盖了所有场景(至少在这个简单示例中),并且这些场景都不需要定义一个以上的通用生命周期(定义'b)。
是否有过需要定义多个通用生命周期的情况?
场景 1:如果您在内部网站上使用自签名证书,则仍在使用加密。(据我所知)最大的安全问题是您的浏览器不会将证书识别为受信任的证书,当您告诉浏览器信任它时,大多数人不会验证您信任的证书实际上是Web 服务器上的证书,而不是用自己的证书替换您的证书的中间人系统。那么这里的安全问题就很清楚了。
场景二:拥有来自实际的、全球可信的CA的有效X509证书,当证书过期时,如果您选择绕过浏览器的警告并使用网站登录,会出现什么安全问题?您仍在使用加密。私钥在 Web 服务器上仍然安全。如果中间人系统尝试替换证书,您可能会收到有关证书无效的浏览器警告,而不是有关证书已过期的警告。
附言。有一篇关于SSL 证书过期的危险的完整文章,但它所做的只是提到了仅适用于公共网站(而不是内部网站)的业务缺点(而不是技术缺点),并提到了诸如“个人信息面临风险”之类的通用声明。中间人攻击”,但他们认为为什么会出现这种情况的解释为零。我不确定他们是否知道。我觉得互联网上的大多数网站都是针对这样一个复杂的主题这样做的——他们说了一个他们认为是正确的通用陈述,但不知道为什么。
我的公司有一个自托管的 GitLab 服务器。我正在编写一个 Ansible 剧本,它使用 GitLab 服务器中的多个项目来配置服务器。
为了让目标服务器自动(非交互式)克隆项目,我使用了部署令牌。
首先,在我们的 GitLab 服务器的 Web 界面上,我进入我的第一个项目并为其生成了一个部署密钥。我可以将目标服务器配置为使用 ansible 的部署密钥,如下所示:
- name: Have git store credentials on disk
community.general.git_config:
name: credential.helper
scope: global
value: store
- name: Add credentials for project A
copy:
dest: /root/.git-credentials
content: "https://{{ gitlab_project_A_deploy_username }}:{{ gitlab_project_A_deploy_password }}@company_gitlab_server.com"
- name: Clone Project A git repo
git:
repo: 'https://company_gitlab_server.com/USER/Project_A.git'
dest: /some/dir/
Run Code Online (Sandbox Code Playgroud)
我设置gitlab_project_A_deploy_username并gitlab_project_A_deploy_password在 ansible 保险库中。这很有效,除了在 中/root/.git-credentials,凭据不是特定于 git-repo 的 - 它们是特定于服务器的。
当我获得项目 B 的部署密钥时,它具有完全不同的用户名和密码,但服务器是相同的。即使我将两组凭据添加到ansible/root/.git-credentials模块git,甚至只是常规git …
我正在查看 的来源gunicorn,这是一个非常受欢迎的项目。
在gunicorn/app/wsgiapp.py模块中,该模块定义了一个类,然后从同一个文件中导入该类:
class WSGIApplication(Application):
...
def run():
from gunicorn.app.wsgiapp import WSGIApplication
WSGIApplication("%(prog)s [OPTIONS] [APP_MODULE]").run()
Run Code Online (Sandbox Code Playgroud)
该类定义在同一个模块中,在上面。为什么需要导入它?
如果我注释掉的第一行run()功能(进口线),gunicorn运行完全正常(不崩溃) -至少在路上我遇到它,用:gunicorn mysite.wsgi:application,mysite是我的测试Django项目的名称。
这是一个备受瞩目的项目,如果不需要此导入,我想现在有人会删除它。这种进口有原因吗?